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.
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([&]{timer.cancel();})</code>
Cependant, le code fourni ne semble pas mettre fin au minuteur comme prévu.
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.
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>
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& ec) { 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"; } }</code>
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!