2

次のasync_write()は、前の async_write() が終了したときに実行する必要があることを知っています(エラーの有無にかかわらず、終了したとき)。

async_write() 呼び出しを行っているときに、これらのいずれかが何らかの理由で長い時間がかかる場合、または終了しない場合に何が起こるかを知りたいです (同期操作のようにタイムアウトはないと仮定します)。この操作が失敗したと見なされるのはいつですか? 終わらないその操作が最終的にOSによって内部的に削除されるのはいつですか? たぶん、タイムアウトが関係していて、私の仮定が間違っていますか?

つまり、書き込み操作は OS に送信され、無期限にブロックされる可能性がありますか? したがって、ハンドラーが呼び出されることはなく、次の async_write() が呼び出されることもありません。

注:複数のスレッドで run() を呼び出していると想定していますが、書き込み操作は順番に送信する必要があるため、書き込みハンドラーがストランドでラップされていると想定しています。

お時間をいただきありがとうございます。

4

1 に答える 1

0

cancel()非同期操作には明示的なタイムアウトはありませんが、IO オブジェクトのメンバー関数を使用してキャンセルできます。これらの操作は、基盤となる OS 呼び出し自体が失敗し、再試行が合理的に発生しない場合にのみ、失敗したと見なされます。たとえば、書き込みが失敗した場合:

  • EINTRの場合、書き込みはすぐに再試行されます。
  • EWOULDBLOCKEAGAIN、またはERROR_RETRYの場合、Boost.Asio は操作をジョブ キューにプッシュします。これは、書き込みバッファがいっぱいになった場合に発生する可能性があるため、操作をキューに戻すと再試行が延期され、他の操作を試行できるようになります。
  • その他のエラーにより、操作が失敗します。

システムコールに無期限ブロックがあってはなりません。Boost.Asio は、基礎となる IO オブジェクトを非ブロッキングに設定し、書き込みがEWOULDBLOCKEAGAIN、またはで失敗した場合に、関連付けられたファイル記述子を待機することにより、同期ブロッキング書き込み動作を提供しますERROR_RETRY

ストランドは、長期間の非同期操作の影響を受けません。ストランドは、操作自体ではなく、ハンドラーの厳密な順次呼び出しを提供するために使用されます。などの合成操作の場合boost::asio::async_write、中間ハンドラも最終ハンドラと同じストランドを介して呼び出されます。全体として、この動作は次のようにスレッド セーフを提供するのに役立ちます。

  • async_write_some中間ハンドラーから開始されたすべての操作は、ストランド内にあります。
  • 操作自体はストランド内にはありません。これにより、実際の書き込みが行われている間に他のハンドラーを実行できます。
  • ユーザー ハンドラーはストランド内で呼び出されます。

この回答は、構成された操作とストランドについてさらに洞察を提供する可能性があります。

于 2013-01-31T14:34:42.557 に答える