Maison > développement back-end > C++ > Comment puis-je annuler en toute sécurité un minuteur Boost Asio, même s'il est déjà expiré ?

Comment puis-je annuler en toute sécurité un minuteur Boost Asio, même s'il est déjà expiré ?

DDD
Libérer: 2024-10-30 01:00:28
original
225 Les gens l'ont consulté

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

Annuler le minuteur Boost Asio en toute sécurité

Cet article abordera le sujet de l'annulation en toute sécurité d'un boost::asio::basic_waitable_timer en étudiant un exemple de code fourni et son comportement inattendu.

Le problème

L'objectif est d'annuler un minuteur en utilisant l'approche recommandée consistant à publier une demande d'annulation au service d'E/S :

<code class="cpp">timer.get_io_service().post([&amp;]{timer.cancel();})</code>
Copier après la connexion

Cependant, le code fourni ne semble pas mettre fin au minuteur comme prévu.

Enquête sur le problème

Le code utilise une combinaison de service d'E/S, de délai et de threads pour créer un scénario dans lequel la minuterie est démarrée et annulée simultanément.

Le problème survient lorsque l'annulation est tentée alors que la minuterie est déjà expirée. Dans ce cas, la requête Cancel() publiée ne prend pas effet. Par conséquent, le gestionnaire d'achèvement du minuteur continue de se déclencher, provoquant le blocage du thread principal indéfiniment.

Détection et gestion de l'annulation incomplète

Pour résoudre ce problème, nous avons besoin d'un moyen de détecter si le minuteur n'a pas été annulé. Une approche consiste à utiliser le point temporel d'expiration du minuteur et à lui attribuer une valeur spéciale « invalide » lorsque l'annulation est initiée :

<code class="cpp">timer.get_io_service().post([](){
    timer.expires_at(Timer::clock_type::time_point::min());
});</code>
Copier après la connexion

Dans le gestionnaire d'achèvement, si le point temporel d'expiration est défini sur cette valeur non valide , le gestionnaire peut reconnaître que le minuteur n'a pas été annulé et le gérer en conséquence :

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

Résumé

Bien que l'annulation des opérations asynchrones dans Boost Asio soit généralement sûre, il est important de prendre en compte les cas où l'opération peut être déjà terminée avant la réception de la demande d'annulation. L'utilisation d'une logique supplémentaire pour détecter et gérer de tels scénarios garantit une annulation robuste des tâches asynchrones.

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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal