Maison > développement back-end > C++ > Comment annuler de manière fiable un minuteur Boost ASIO Deadline Timer dans un fil de discussion séparé ?

Comment annuler de manière fiable un minuteur Boost ASIO Deadline Timer dans un fil de discussion séparé ?

Barbara Streisand
Libérer: 2024-10-29 07:03:30
original
514 Les gens l'ont consulté

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

Annuler le minuteur Boost ASIO Deadline Timer en toute sécurité

Le code fourni est destiné à annuler un boost::asio::basic_waitable_timer en toute sécurité dans un fil de discussion séparé . Cependant, il semble que l'annulation ne fonctionne pas comme prévu en raison d'un problème sous-jacent.

Comprendre le problème :

Le problème vient du fait que le code fourni tente d'annuler le minuteur à l'aide de la fonction post, qui ajoute l'opération d'annulation à la file d'attente des événements du io_service du minuteur. Cette approche est problématique car si le minuteur a déjà expiré avant l'exécution de l'opération d'annulation, l'opération d'annulation sera ignorée, laissant effectivement le minuteur dans un état actif.

Résoudre le problème :

Pour résoudre ce problème, nous devons concevoir un moyen robuste d'annuler la minuterie quel que soit son état actuel. Une approche efficace consiste à introduire une valeur sentinelle pour le moment d’expiration du temporisateur qui signifie un état invalide. En définissant l'expiration du minuteur sur cette valeur sentinelle pendant le processus d'annulation, nous pouvons garantir que même si le minuteur a expiré avant l'annulation, il sera placé dans un état invalide, empêchant ainsi toute autre opération asynchrone.

Code modifié :

Implémenter l'approche de valeur sentinelle :

<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>
Copier après la connexion

Gestion du gestionnaire d'achèvement :

Dans le gestionnaire d'achèvement , vérifiez la valeur sentinelle pour détecter l'arrêt :

<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>
Copier après la connexion

Avec l'approche de la valeur sentinelle, vous pouvez désormais annuler de manière fiable la minuterie même si elle a déjà expiré.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal