スレッドで 64 個を超えるソケットを操作するのは危険 (?) であると読みました。しかし、少なくとも私にとっては、複雑なスレッドの問題を回避するためにノンブロッキングソケットが使用されます。リスナーソケットは 1 つしかないため、ソケットをスレッドに分割して select() で使用するにはどうすればよいですか? スレッドごとに fd_sets を作成する必要がありますか? そして、 CreateThread() で最初に値を渡すことしかできないので、クライアントをスレッドに割り当てるにはどうすればよいですか?
3 に答える
いいえ、いいえ、いくつか間違っています。
まず、多くのソケットを処理する理想的な方法は、ソケット (クライアント) の前で作業を行うスレッド プールを用意することです。
別の 1 つまたは 2 つのスレッド (実際には、私が知る限り、CPU の量) が接続の受け入れを行います。
これで、新しい接続などのイベントが発生すると、スレッド プールにディスパッチされて処理されます。
次に、実際の実装と環境に依存します。
たとえば、Windows にはIOCPと呼ばれるものがあります。
あなたが私に尋ねるなら - 下位の実装を気にせず、代わりにBOOST::ASIOやACEなどのフレームワークを使用してください。
個人的にはASIOが好きです。これらのフレームワークの最も良い点は、通常クロスプラットフォーム (nix、Windows など) であることです。
したがって、私の答えは少し広いですが、コード/マニュアル/実装に飛び込む前に、これらの事実を考慮に入れるのが最善だと思います.
幸運を!
さて、あなたが読んだことは間違っています。多くの強力なシングルスレッドアプリケーションは、ノンブロッキング ソケットと高性能 I/O デマルチプレクサ (epoll(4)
およびなど) を使用して作成されていkqueue(2)
ます。それらの利点は、待機イベントを事前にセットアップすることです。そのため、カーネルは大量のファイル記述子をコピーしたり、ポーリングごとに多くのものを[再]セットアップしたりする必要がありません。
次に、主な目標がレイテンシーではなくスループットである場合、スレッド化には利点があります。
利用可能な手法の概要をご覧ください: The C10K problem。
「多くのソケットを処理する理想的な方法」は、Poni が信じているように、「スレッドプールを持つ」ことであるとは限りません。
「理想」とは何ですか?プログラミングのしやすさですか?最高のパフォーマンス?
彼は「下位の実装にこだわらず」、「BOOST::ASIO や ACE などのフレームワークを使用する」ことを推奨しているので、プログラミングの容易さを意味していると思います。
彼が Windows でのパフォーマンスの角度を持っていたら、「IOCP と呼ばれるもの」を推奨したでしょう。IOCP は「IO コントロール ポート」であり、ほんの一握りのスレッド (使用可能なコアごとに 1 つを推奨) を使用して超高速 IO アプリケーションを実装できます。IOCP アプリケーションは、彼がそれらを使用してコードを書いたことがあれば知っていたであろうスレッドプールの同等物を巡回します。IOCP はスレッド プールと一緒に使用されるのではなく、スレッド プールの代わりに使用されます。
Linux には IOCP に相当するものはありません。
Windows でフレームワークを使用すると、製品の「市場投入までの時間」が短縮される可能性がありますが、パフォーマンスは、純粋な IOCP 実装が選択された場合とはかけ離れています。
パフォーマンスの違いは、OS 固有のコードの実装を考慮する必要があるようなものです。とにかく一般的なソリューションが選択された場合、少なくともパフォーマンスは「偶然に与えられたものではない」でしょう.