Destructeurs bloqués dans les futurs asynchrones
Lorsqu'un futur est renvoyé par std::async, son destructeur devient implicitement bloquant, conduisant à l'appel fil en pause. Bien que ce comportement puisse sembler surprenant, il est intentionnel pour des raisons de sécurité et d'exactitude.
Raisons du blocage des destructeurs
Comme indiqué par Hans Boehm dans le livre blanc "N3679 : Async( ) les futurs destructeurs doivent attendre", les futurs renvoyés par async() attendent que leur état partagé associé soit prêt dans leurs destructeurs. Cela évite un scénario dans lequel le thread associé continue de s'exécuter sans aucun moyen d'attendre son achèvement une fois le futur détruit. Sans mesures supplémentaires, un tel thread « incontrôlable » pourrait s'étendre au-delà de la durée de vie de ses objets dépendants, provoquant potentiellement un « smash de mémoire » entre threads et des vulnérabilités de sécurité.
Exemple
Considérez cet extrait de code :
std::future<int> future = std::async(std::launch::async, run_async_task);
Si le destructeur du futur ne bloque pas, le thread exécutant run_async_task pourrait continuer à s'exécuter même après la destruction du futur. Si ce fil accède à des objets qui ont déjà été détruits, une erreur d'exécution se produira.
Approche alternative
Pour éviter un comportement bloquant, appelez explicitement future.get() ou future.wait() avant de détruire le futur. Cela garantit que la tâche associée est terminée et ne dépend plus du futur détruit.
Mise à jour
Le « Trip Report » de Michael Wong suite à la réunion du C Standard en septembre 2013 fournit une perspective actualisée sur ce sujet. Bien qu'il y ait eu des discussions importantes, aucun changement n'a été apporté au comportement de blocage des destructeurs std::future. De plus, une proposition visant à déprécier l'utilisation de l'async a finalement été rejetée.
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!