5

小さな 3 つのサーバーと 1 つのクライアント プログラムを作成しています。2 つのサーバーは tcp メッセージを送信し、最後のサーバーは winsock2 を使用して upd データグラムを送信します。

スレッド (OpenMP または boost::threads) を使用して同時に recvfrom() を作成して、2 つのスレッドが同じポートの同じソケットから同時にリッスンできるかどうか疑問に思っています。

Windows7 で VC++ 2010 を使用しています。

ご協力ありがとうございました。

4

2 に答える 2

8

はい、ソケットはスレッドセーフですが、注意が必要です。1 つの一般的なパターン (ブロッキング IO を使用する場合) は、1 つのスレッドがソケットでデータを受信し、別のスレッドが同じソケットでデータを送信することです。ソケットからデータを受信する複数のスレッドを持つことは、通常、UDP ソケットでは問題ありませんが、ほとんどの場合、TCP ソケットではあまり意味がありません。WSARecvのドキュメントに次の警告があります。

WSARecv は、異なるスレッドから同時に同じソケットで呼び出されるべきではありません。これは、予期しないバッファー順序になる可能性があるためです。

ただし、UDP を使用していて、プロトコルがステートレスである場合、これは通常は問題になりません。

WSAEINPROGRESSまた、エラー コードは主に Winsock 1.1 に適用されることに注意してください。

WSAEINPROGRESS: ブロッキング Windows Sockets 1.1 呼び出しが進行中か、サービス プロバイダーがまだコールバック関数を処理中です。

そしてWSAEINPROGRESSさらなる状態の説明:

現在作戦進行中。

ブロッキング操作が現在実行中です。Windows ソケットでは、1 つのブロック操作 (タスクまたはスレッドごと) のみを未処理にすることができます。他の関数呼び出しが行われた場合 (それがそのソケットまたは他のソケットを参照しているかどうかに関係なく)、関数は WSAEINPROGRESS エラーで失敗します。

これは、タスクまたはスレッドごとの単一のブロック操作について話していることに注意してください。

さらに、WSARecv のドキュメントには追加の警告があります。

同じスレッドで進行中のブロッキング Winsock 呼び出しを中断した APC 内で別のブロッキング Winsock 呼び出しを発行すると、未定義の動作が発生するため、Winsock クライアントによって試行されてはなりません。

しかし、それらの警告は別として、あなたは大丈夫なはずです。

更新: いくつかの外部参照を追加するには: alt.winsock.programming: Is socket thread-safe? Winsock Programmer's FAQ: Winsockはスレッドセーフですか?

于 2012-12-21T10:11:13.043 に答える
1

Winsock では、ソケットで 1 つのブロッキング IO 呼び出しのみが許可されます。異なるスレッドからの複数のブロッキング呼び出しは、「WSAEINPROGRESS」エラーで終了します。http://msdn.microsoft.com/en-us/library/windows/desktop/ms740668%28v=vs.85%29.aspx#WSAEINPROGRESS .

同時 IO 要求を行いたい場合は、非同期 IO またはオーバーラップ IO (Windows 用語で) を使用してみてください。しかし、データの同時読み取りよりも、データの同時処理が必要になると思います。その場合、1 つのスレッドが IO 要求を発行し、他のスレッドが処理するようにすることができます。

于 2012-12-21T02:48:12.897 に答える