2

前回の書き込みが完了する前に、boost::asio ソケットに 2 回目の書き込みを行おうとするとどうなるかについては、何もわかりませんでした。これは、多くの非同期プログラムで潜在的に発生する可能性のあるもののようです (最初の書き込みを行った後、プログラムは終了を待つ前に続行し、2 番目のメッセージが送信される可能性があります)。起こりうることをいくつか考えてみました (これは、すべての場合において、メッセージが async_write への 1 回の呼び出しで送信されることを前提としています)。

void handleWrite(const boost::system::error_code&error)
{
    if(error)throw NetError(error);
}

vodi sendStuff()
{
    const char msg1 = "Red, Green, Blue";
    const char msg2 = "One, Two, Three";

    asio::async_write(socket,asio::buffer(msg1,sizeof(msg1)),boost::bind(&handleWrite,_1));
    //assume msg1 has still not been sent by the time we get here
    asio::async_write(socket,asio::buffer(msg2,sizeof(msg2)),boost::bind(&handleWrite,_1));
}

したがって、最初の送信でエラーが発生しないと仮定します。

  • Asio は msg1、msg2 の順に送信します。単一の TCP パケットでも可能です。
  • 2 番目の async_write 呼び出しは、msg1 が完了するまでブロックされます
  • 結果は未定義です

msg1s でエラーが発生した場合、例外によって msg2 も中止されると思いますか?

また、関連付けられた io_service にスレッド プールがあるか、それとも単一のスレッドしかないかによって影響を受けますか?

安全でない場合、送信するメッセージのキューを維持し、それらを1つずつ送信し、書き込みハンドラーが例外をスローした場合に中止する単純なラッパーを作成した人はいますか?

4

1 に答える 1

1

したがって、通常のノンブロッキング ソケットを使用すると、実装に依存する量のものをソケットに書き込むことができます。その後、最終的に書き込みは -EWOULDBLOCK を返し、後で再試行できるように書き込みを行いません。ソースを調べてみると、Boost はそれをラップしているため、最終的にはすべての書き込みがそこに到達するはずです (または、would_block や try_again を含まないエラーが発生します)。

于 2010-01-20T10:19:16.477 に答える