web-dev-qa-db-ja.com

同じソケットでのsend / recvへの並列呼び出しは有効ですか?

  1. 同じソケットで1つのスレッドからsendを呼び出し、別のスレッドからrecvを呼び出すことはできますか?
  2. 同じソケット上の異なるスレッドから複数の送信を並列に呼び出すことはできますか?

良いデザインはこれを避けるべきであることは知っていますが、これらのシステムAPIがどのように動作するかは明確ではありません。私も同じための良いドキュメントを見つけることができません。

方向にポインターがあれば役立ちます。

115
Jay

POSIXは、send/recvをアトミック操作として定義しているため、POSIX send/recvについて話していると仮定して、はい、複数のスレッドから同時に呼び出すことができ、動作します。

これは必ずしもそれらが並行して実行されることを意味するわけではありません-複数の送信の場合、最初の送信が完了するまで2番目の送信がブロックされる可能性があります。送信はデータをソケットバッファに入れると完了するので、おそらくそれほど気付かないでしょう。

SOCK_STREAMソケットを使用している場合、並列処理をしようとすると、send/recvがメッセージの一部のみを送受信する可能性があるため、役に立たない可能性が低くなります。

SOCK_STREAMソケットでのsend/recvのブロックは、少なくとも1バイトを送信またはrecvするまでブロックするだけなので、ブロックと非ブロックの違いは役に立ちません。

83
Chris Dodd

ソケット記述子は、特定のスレッドではなく、プロセスに属します。したがって、異なるスレッドの同じソケットとの間で送受信を行うことができ、OSが同期を処理します。

ただし、送信/受信の順序が意味的に重要な場合は、スレッドの場合と同様に、ユーザー自身(それぞれコード)が異なるスレッドでの操作間の適切な順序付けを保証する必要があります。

16

並列受信がどのように達成できるかはわかりません。 3バイトのメッセージがある場合、1つのスレッドが最初の2バイトを取得し、別のスレッドが最後のバイトを取得できますが、どちらがどちらであったかを知る方法はありません。メッセージが1バイトしかない場合を除き、受信する複数のスレッドで何かを確実に機能させる方法はありません。

複数の送信might 1回の呼び出しでメッセージ全体を送信した場合は動作しますが、わかりません。別のものを上書きする可能性があります。確かにそうすることによるパフォーマンス上の利点はありません。

複数のスレッドを送信する必要がある場合は、同期メッセージキューを実装する必要があります。キューからメッセージを読み取る実際の送信を行う1つのスレッドがあり、他のスレッドがメッセージ全体をキューに入れます。同じことは受信に対しても機能しますが、受信スレッドはメッセージの形式を認識して、メッセージを適切に逆シリアル化する必要があります。

4
noah