ホームページ >バックエンド開発 >C++ >Boost Asio Deadline タイマーがすでに期限切れになっている場合でも、安全にキャンセルするにはどうすればよいですか?

Boost Asio Deadline タイマーがすでに期限切れになっている場合でも、安全にキャンセルするにはどうすればよいですか?

DDD
DDDオリジナル
2024-10-30 01:00:28197ブラウズ

How Can I Safely Cancel a Boost Asio Deadline Timer, Even If It's Already Expired?

Boost Asio Deadline Timer を安全にキャンセルする

この記事では、提供されているコード例とそのコード例を調査することで、boost::asio::basic_waitable_timer を安全にキャンセルする方法について詳しく説明します。予期しない動作。

問題

目的は、I/O サービスにキャンセル要求を送信するという推奨アプローチを使用して、期限タイマーをキャンセルすることです。

<code class="cpp">timer.get_io_service().post([&amp;]{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&amp; ec)
{
    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";
    }
}</code>

概要

Boost Asio での非同期操作のキャンセルは一般に安全ですが、ケースを考慮することが重要です。この場合、キャンセル要求が受信される前に操作がすでに完了している可能性があります。追加のロジックを使用してこのようなシナリオを検出して処理すると、非同期タスクの確実なキャンセルが確実になります。

以上がBoost Asio Deadline タイマーがすでに期限切れになっている場合でも、安全にキャンセルするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。