5

複数のスレッドから同じソケットに関数呼び出しを書き込む

安全ですか?それらの間に同期を追加したいですか?ネットワーク層からアプリケーション層へのアプリケーションの書き込み/読み取りが遅れるなどの問題が発生しますか?

Linux Redhat 環境で GNU C++ ライブラリ GCC 4 を使用しています。

これはサーバー側のプロセスであり、サーバーとクライアントの間にソケット接続は 1 つしかありません サーバーとクライアントは 2 つの異なるマシン上にあります データはサーバーからクライアントへクライアントからサーバーへ送信されます

問題1-サーバーがクライアント側にデータを送信する場合(複数のスレッドが同じ単一ソケットを介してクライアント側にデータを書き込みます)しかし、一部のスレッドから書き込まれたデータはクライアント側に送信されず、同じネットワーク層にも送信されませんマシン (Tcpdump にはそのデータがありません)

問題 2 - クライアントがサーバーにデータを送信するとき クライアントによるサーバーのデータ送信がサーバーの TCPdump に表示され、ループ内の「読み取り」および「選択」機能を使用して単一のスレッドからソケットから読み取っているサーバー アプリケーションに対して受信されない

これらの問題が発生するパターンを特定できませんでした これは、非常に多くの複数のスレッドが同じソケットに書き込みを行っているときに発生したと考えられます OS が同期を処理することを期待して、書き込み関数を同期していません

4

3 に答える 3

1

write() はライブラリ関数ではなくシステム コールであり、システム コールは通常、アトミックであることが保証されています。

于 2012-07-03T10:08:16.617 に答える
0

writeどちらの呼び出しが最初に完了するかは指定されていません。コンテキスト スイッチは、最初の命令で 2 つの書き込みのいずれかを停止させる可能性があります。これにより、任意の順序付けが行われる可能性があります。writeそれについてカーネルができることは何もありません。根本的な問題です。

データは不特定の順序で書き込まれますが、これはおそらく受け入れられません。

于 2014-01-12T18:05:26.857 に答える
0

複数のスレッドから write() を使用するのは安全ではありません。出力が一緒にシャッフルされないという保証はありません。1 回の書き込みでバイトの半分をソケットに書き込み、別の書き込みでバイトの書き込みを開始できます。各書き込みが連続して書き込まれることを確認する必要がある場合 (そして、その保証が必要ないとは考えにくい場合)、ロックまたはその他の同期方法が必要です。

于 2012-06-30T11:33:06.363 に答える