0

async_connect() をタイムアウト付きで実装しようとしています。

    async_connect_with_timeout(socket_type & s,
        std::function<void(BoostAndCustomError const & error)> const & connect_handler,
        time_type timeout);

操作が完了すると、操作結果 (タイムアウトを含む) を示しconnect_handler(error)て呼び出されます。error

タイムアウトの例 1.51のコードを使用したいと思っていました。最大の違いは、io_service.run() を実行する複数のワーカー スレッドを使用していることです。

サンプル コードが機能し続けるには、どのような変更が必要ですか?

私の問題は次のとおりです。

  1. 呼び出す場合:

    Start() {
        socket_.async_connect(Handleconnect);
        dealine_.async_wait(HandleTimeout);
    }
    

    HandleConnect()以前でも別のスレッドで完了することができますasync_wait()(可能性は低いですが可能です)。、、およびをstrandラップする必要がありますか?Start()HandleConnect()HandleTimeout()

  2. HandleConnect()エラーなしで最初に呼び出されたが、「近い将来の呼び出しのためにキューに入れられた」ために失敗した場合はどうなりますdeadline_timer.cancel()か? サンプルコードでソケットを閉じることができるようです。このような動作 (接続後にいくつかの操作を開始した後、タイマーが接続を閉じる) は、深刻な頭痛の種になりやすいです。deadline_timer.expires_from_now()HandleTimeout()HandleTimeout()

  3. HandleTimeout()とが最初に呼び出されたらどうでしょうかsocket.close()HandlerConnect()エラーなしで既に「キューに入れられている」可能性はありますか? ドキュメントには、「非同期の送信、受信、または接続操作はすぐにキャンセルされ、boost::asio::error::operation_abortedエラーが発生して完了します」と記載されています。マルチスレッド環境で「すぐに」とはどういう意味ですか?

4

1 に答える 1

1
  1. 異なるスレッドでの並列実行を防ぎたい場合は、各ハンドラーをストランドでラップする必要があります。一部の完了ハンドラーがタイマーにアクセスすると思うので、ストランドでsocket_ラップする必要があります。Start()しかし、CPU ごとの io_service モデルを使用する方がはるかに簡単ではないでしょうか。つまり、アプリケーションをio_serviceプールに基づいて作成するのです。私見、頭痛がずっと少なくなります。

  2. はい、可能です。なぜそれは頭痛ですか?「偽のタイムアウト」のためにソケットが閉じられ、ネットワーク障害のために閉じられたかのように、再接続(またはその他)の手順を開始します。

  3. はい、それも可能ですが、繰り返しになりますが、正しく設計されたプログラムでは問題は発生しませんHandleConnect。閉じたソケットで何らかの操作を発行しようとすると、適切なエラーが発生します。とにかく、データを送受信しようとすると、現在のソケット/ネットワークの状態がよくわかりません。

于 2012-11-21T16:39:42.757 に答える