libevを使用してtcpサーバーを作成しています。ソケットを作成し、listen() の後に fork してから、libev read watcher を listen ソケットで開始し、watcher コールバックでクライアント接続を受信しています。子と親 (複数ある場合は 2 つの子) の両方が、リッスンしているソケットが読み取り可能になったというイベントを受信し、両方が accept() クライアント接続を試行し、この場合、プロセスの 1 つがブロックされる場合がありますか? テスト プログラムを書いたところ、read-ready イベントを受け取るプロセスは 1 つだけのようですが、間違っているのでしょうか? この場合のシステムの動作についてどこで読むことができますか? カーネルはどのようにプロセス間の負荷分散を行い、誰がイベントを受け取るかを決定しますか? バックエンド (select、epoll など) および/または OS 固有ですか?
質問する
102 次
1 に答える
1
両方のプロセスがソケットから準備完了の通知を受け取り、結果として両方が を呼び出す可能性は非常に高いaccept()
です。socket()
これが、 、poll()
、epoll()
、またはkqueue()
(またはこれらの 1 つ以上の抽象化を提供する libev)などのイベントベースの API で常に非ブロッキング ファイル記述子を使用する必要がある理由の 1 つです。非ブロッキング ソケットを使用すると、1 つの子が成功した結果をaccept()
取得し、他のすべての子が を取得しEAGAIN
、それを無視して、害を及ぼすことなくスリープ状態に戻ります。
于 2013-01-01T09:10:34.573 に答える