この記事では、提供されているコード例とそのコード例を調査することで、boost::asio::basic_waitable_timer を安全にキャンセルする方法について詳しく説明します。予期しない動作。
目的は、I/O サービスにキャンセル要求を送信するという推奨アプローチを使用して、期限タイマーをキャンセルすることです。
<code class="cpp">timer.get_io_service().post([&]{timer.cancel();})</code>
ただし、提供されたコードは意図したとおりにタイマーを終了していないようです。
このコードは、I/O サービス、デッドライン タイマー、スレッドの組み合わせを使用して、タイマーの開始とキャンセルが同時に行われるシナリオ。
タイマーがすでに期限切れになっているときにキャンセルしようとすると、問題が発生します。その場合、ポストされた cancel() リクエストは有効になりません。その結果、タイマーの完了ハンドラーが起動し続け、メイン スレッドが無期限にブロックされます。
これに対処するには、タイマーが終了したかどうかを検出する方法が必要です。キャンセルされなかった。 1 つのアプローチは、タイマーの有効期限タイムポイントを使用し、キャンセルの開始時に特別な「無効な」値をそれに割り当てることです。
<code class="cpp">timer.get_io_service().post([](){ timer.expires_at(Timer::clock_type::time_point::min()); });</code>
完了ハンドラーで、有効期限タイムポイントがこの無効な値に設定されている場合、ハンドラーはタイマーがキャンセルされていないことを認識し、それに応じて処理できます。
<code class="cpp">void handle_timeout(const boost::system::error_code& ec) { if (timer.expires_at() != Timer::time_point::min()) { timer.expires_from_now(std::chrono::milliseconds(10)); timer.async_wait(&handle_timeout); } else { std::cerr << "handle_timeout: detected shutdown\n"; } }</code>
Boost Asio での非同期操作のキャンセルは一般に安全ですが、ケースを考慮することが重要です。この場合、キャンセル要求が受信される前に操作がすでに完了している可能性があります。追加のロジックを使用してこのようなシナリオを検出して処理すると、非同期タスクの確実なキャンセルが確実になります。
以上がBoost Asio Deadline タイマーがすでに期限切れになっている場合でも、安全にキャンセルするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。