このプログラムは、Linux 上の C で開発されているクライアント サーバー ソケット アプリケーションです。各クライアントが接続し、自分自身をオンラインとしてログに記録するリモート サーバーがあります。常に複数のクライアントがオンラインである可能性が高く、すべてがサーバーに接続して、オンライン/ビジー/アイドルなどとしてログに記録しようとします。サーバーはこれらの同時要求をどのように処理できますか。良い設計アプローチは何ですか (おそらく、接続要求ごとにフォーク/マルチスレッド化しますか?)
5 に答える
個人的には、サーバーにはイベント駆動型のアプローチを使用します。そこで、接続が到着するとすぐに呼び出されるコールバックを登録します。ソケットの読み取りまたは書き込みの準備ができたときのイベント コールバック。
大量の接続を使用すると、スレッドと比較してパフォーマンスとリソースのメリットが大幅に向上します。しかし、接続数が少ない場合にもこれを好みます。
本当に複数のコアを使用する必要がある場合、または処理に時間がかかる可能性のある要求があり、スレッドなしで処理するには複雑すぎる場合にのみ、スレッドを使用します。
イベント駆動型ネットワークを処理するための基本ライブラリとしてlibevを使用します。
一般的に、リクエストを処理するためのスレッドプールが必要です。
一般的な構造は、着信要求をキューに入れるだけの単一スレッドで始まります。あまり効果がないため、通常、1つのスレッドがネットワークの最大速度に追いつくのは非常に簡単です。
これにより、アイテムはある種の同時キューに入れられます。次に、他のスレッドのプールがキューからアイテムを読み取り、必要な処理を実行してから、結果を別のキューに格納します(繰り返し、サーバーがシャットダウンするまで繰り返します)。
最後に、結果キューからアイテムを取得し、クライアントに応答を送信する別の単一スレッドがあります。
Comerの「InternetworkingwithTCP/ IP」ボリューム3(BSDソケットバージョン)を見てください。サーバーとクライアントを作成するさまざまな方法の詳細な例があります。完全なコード(残念ながら説明はありません)はWeb上にあります。または、http: //tldp.orgを調べてみると、チュートリアルのコレクションがあります。
最善のアプローチは、イベント ドリブン モデルとマルチスレッド モデルの組み合わせです。
ノンブロッキング ソケットを多数作成しますが、スレッド数ははるかに少ないはずです。つまり、スレッドごとに 10 個のソケット。
次に、ノンブロッキング モードですべてのスレッドでイベント (着信要求) をリッスンし、発生したときにそれを処理します。
通常、この手法は、ノンブロッキング ソケットまたはマルチスレッド モデルを個別に使用するよりも優れたパフォーマンスを発揮します。
select または poll または epoll
これらは、複数のイベント ソース (接続) を単一の待機ポイントに集約する *nix システムの機能です。サーバーは接続をデータ構造に追加し、select などを呼び出して待機します。サーバーは、これらの接続のいずれかで問題が発生すると起動し、どの接続かを判断して処理し、スリープ状態に戻ります。詳細はマニュアルを参照してください。
これらのメカニズムの上に構築されたいくつかの高レベルのライブラリがあり、libevent、libev などのプログラミングをいくらか容易にします。