Boost ASIO Deadline Timer を安全にキャンセルする
提供されたコードは、別のスレッド内で boost::asio::basic_waitable_timer を安全にキャンセルすることを目的としています。 。ただし、根本的な問題により、キャンセルが期待どおりに機能していないようです。
問題の理解:
この問題は、提供されたコードがpost 関数を使用してタイマーをキャンセルしようとします。これにより、タイマーの io_service のイベント キューにキャンセル操作が追加されます。このアプローチには問題があります。キャンセル操作が実行される前にタイマーがすでに期限切れになっている場合、キャンセル操作は無視され、実質的にタイマーがアクティブな状態のままになるためです。
問題の解決:
この問題に対処するには、現在の状態に関係なくタイマーをキャンセルする堅牢な方法を考案する必要があります。効果的なアプローチの 1 つは、無効な状態を示すタイマーの有効期限ポイントのセンチネル値を導入することです。キャンセル プロセス中にタイマーの有効期限をこのセンチネル値に設定すると、キャンセル前にタイマーが期限切れになった場合でも無効な状態になり、それ以上の非同期操作を効果的に防止できます。
変更されたコード:
センチネル値アプローチの実装:
<code class="cpp">timer.get_io_service().post([](){ std::cerr << "tid: " << std::this_thread::get_id() << ", cancelling in post\n"; // Cancel: timer.expires_at(Timer::clock_type::time_point::min()); });</code>
完了ハンドラー処理:
完了ハンドラー内、シャットダウンを検出するためにセンチネル値を確認します:
<code class="cpp">void handle_timeout(const boost::system::error_code& ec) { if (!ec) { started = true; 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"; } } else if (ec != boost::asio::error::operation_aborted) { std::cerr << "tid: " << std::this_thread::get_id() << ", handle_timeout error " << ec.message() << "\n"; } }</code>
センチネル値のアプローチにより、タイマーがすでに期限切れになっている場合でも確実にタイマーをキャンセルできるようになりました。
以上が別のスレッドでブースト ASIO デッドライン タイマーを確実にキャンセルするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。