別のスレッドでブースト ASIO デッドライン タイマーを確実にキャンセルするにはどうすればよいですか?

Barbara Streisand
リリース: 2024-10-29 07:03:30
オリジナル
476 人が閲覧しました

How to reliably cancel a Boost ASIO Deadline Timer in a separate thread?

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&amp; ec)
{
    if (!ec) {
        started = true;
        if (timer.expires_at() != Timer::time_point::min()) {
            timer.expires_from_now(std::chrono::milliseconds(10));
            timer.async_wait(&amp;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 サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート