6

非同期 I/O を使用しているのは、呼び出しスレッドをブロックせず、舞台裏でスレッド処理を行うためです。同じ Stream で BeginWrite() のような複数の非同期操作を呼び出す場合、データ バッファーの内容が混在することを心配する必要がありますか?

3つのバッファを送信したいとしましょう:

Buffer1: 1111111111
Buffer2: 2222222222
Buffer3: 3333333333

バッファが間違った順序で送信されても​​かまわないので、

333333333311111111112222222222

大丈夫ですが、バッファの内容が完全に混ざっている可能性はありますか?

122213121212122333313111223333

PS: 誰かがすでに何らかの形でこれを尋ねていると 100% 確信しています...

4

2 に答える 2

8

Stream の実装に依存します。たとえば、ソケットは読み取りと書き込みの両方で複数の重複した要求をサポートし、ファイル API も同様です。これらは、各操作の一貫性 (コンテンツのインターリーブなし) と操作の順序を保証します。たとえば、ソケット読み取りの場合、受信したバイトは、ポストされた順序でポストされたバッファに配置されます。これらの保証が提供されない場合、高性能ネットワーク IOにはオーバーラップする送信が必要ですが、実際にはオーバーラップする受信が必要なため、高性能ネットワーク アプリケーションを作成することは不可能です。この動作は、古き良きWindows Sockets 2.0: Write Scalable Winsock Apps Using Completion Portsを含む多くの記事で説明されており、MSDN で文書化されています重複する入力/出力:

送信操作と受信操作の両方をオーバーラップできます。受信関数は、着信データの準備として受信バッファーをポストするために複数回呼び出される場合があり、送信関数は、送信される複数のバッファーをキューに入れるために複数回呼び出される場合があります。一連のオーバーラップされた送信バッファは指定された順序で送信されますが、対応する完了指示は異なる順序で発生する可能性があることに注意してください。同様に、受信側では、バッファは供給された順序で満たされますが、完了指示は異なる順序で発生する場合があります。

当然のことながら、同じ保証が世界の管理された側に引き継がれます。クラスNetworkStream:

読み取り操作と書き込み操作は、同期を必要とせずに NetworkStream クラスのインスタンスで同時に実行できます。書き込み操作用に 1 つの固有のスレッドがあり、読み取り操作用に 1 つの固有のスレッドがある限り、読み取りスレッドと書き込みスレッドの間に相互干渉はなく、同期は必要ありません。

そうは言っても、ストリームでランダムに非同期の読み取りと書き込みをスローすると、すぐに混乱が生じます。アプリケーションは、スレッドが操作を送信する順序を慎重に調整して、順序が決定論的となるようにする必要があります。通常、これは、同期ロックを保持しながら非同期操作の呼び出しを実行するために、特別な注意を払って (同期された) リストにアカウンティングを保持することを意味します。

最後に、これらすべての非同期 API では、完了の順序が送信の順序と一致することが保証されていないという特別な注意事項があります。

于 2011-05-20T21:55:04.920 に答える
0

いいえ、ファイル ストリームは複数の同時 IO をサポートしていません。Windows ファイル システムは、これをうまく処理できません。ほぼ確実に例外がスローされます。

編集:

同期と重複した入出力は、ファイル システムが複数の重複した IO 要求を正しく処理することを示しているようです。私の悪い。

ただし、 で同時同期書き込みを実行しようとしないでくださいFileStreamそれは例外をスローします。

于 2011-05-20T21:48:34.747 に答える