3

boost::asio非同期TCP接続を使用して、でコードを書いています。私はそれについていくつかの疑問を持っていることを認めざるを得ません. これらはすべて並行性に関するものです。ここにあるいくつかの:

  • async_write最初のソケットの完了を待たずに同じソケットで2 つ以上を開始するとどうなりますか? ハンドラ (およびasync_write) はオーバーラップしますか、それともasioシリアライゼーションと同期を提供しますか?

  • 上記とasync_connectとの同じ質問async_read。一般に、これらの関数を異なるスレッドから呼び出すことは安全です (異なるバッファーの使用について話しているわけではありません。それは別の問題です...)。

4

2 に答える 2

3

あなたの質問から、単一のインスタンスがあり、複数のスレッドからそれio_serviceを呼び出したいと思います。async_write()

async_write()最終的に次のpost()メソッドを呼び出しますio_serviceこれにより、ロックが取得され、書き込まれるビットがワーク キューにプッシュされ、ビットがインターリーブされて書き込まれないことが保証されます。これらのビットは最終的に書き出され、それらを保持する基礎となるデータ構造 (char 配列など) は、書き込みが完了したことを示すコールバックを取得するまで有効なままにする必要があります。完了ハンドラーとまったく同じコールバック関数を使用している場合、2 つの書き込みのどちらがその関数が呼び出されたかを知る方法がなく、その関数がスレッドセーフでないことを行う場合、動作が未定義または正しくない可能性があります。この状況を処理する一般的な方法は、完了ハンドラーである構造体のインスタンスを作成することです (call () 演算子をオーバーロードするだけです)。

ただし、共有ロックがないと、どのスレッドがそのasync_write()メソッドを実際に実行するかを制御する方法がありません。実際、2 つのスレッドを起動して 1 つのスレッドをすぐに呼び出しasync_write()、もう 1 つのスレッドを 1 時間スリープさせてから を呼び出したasync_write()としても、OS がスレッドをばかげてスケジュールし、2 番目のスレッドの呼び出しを最初に実行しなかったことは保証されません。 . (例は病的ですが、ポイントは普遍的に有効です。)

同じ状況が にも当てはまりますasync_read()。確かに呼び出しをインターリーブできます (つまりasync_read()、完了ハンドラーが呼び出される前に 1 つ実行してから別の呼び出しを実行します) が、これを保証する何らかの外部手段がなければ、意図した順序で が実行されるという保証はありません。

于 2009-12-18T22:05:01.577 に答える
0

同じソケットで2つの非同期操作を開始すると、どちらの順序でも発生する可能性があります。異なるバッファを使用している限り、クラッシュしないという点で「安全」ですが、そのような動作はほとんどありません。

于 2009-12-16T16:02:10.633 に答える