Ce qui arrive quand une exception n'est pas gérée dans un multithread C++11 programme?
Si j'ai un C++11 exécution du programme, les deux fils, et l'un d'eux déclenche une exception non gérée, ce qui se passe? L'ensemble du programme de mourir d'une mort certaine? Sera le fil où l'exception est levée, mourir seul (et si oui, puis-je obtenir une exception dans ce cas)? Tout autre chose?
- Assez sûr, le thread va mourir et vous ne pouvez pas prendre soin " de lui sans l'attraper à l'intérieur de ce thread...mais je pense que les autres threads continuent. Aimerait entendre une réponse faisant autorité bien.
- Certes, je ne parierais pas que le processus de survivre. Je me demande si avec
exception_ptr
nous pouvons espérer qu'à l'exception de propagation à travers les threads, ce serait bien. - Semble que j'avais tort. Grande question.
- Une exception qui est ensuite canalisée vers un autre thread pendant un appel inter-threads ne serait pas considéré comme "non gérée", de l'OMI.
Vous devez vous connecter pour publier un commentaire.
Rien n'a vraiment changé. Le libellé de la n3290 est:
Le comportement de
terminate
peut être personnalisé avecset_terminate
, mais:De sorte que le programme se termine dans un tel cas, les autres threads ne peut pas continuer à fonctionner.
std::exception_ptr
permet des exceptions à être migrées à partir d'un thread à l'autre, est-ce la propagation automatisé de sorte que l'exception est levée dans le thread appelant ? (Sans doute, cela pourrait être difficile)std::thread t(f); try { t.run() } catch(...) { }
?std::terminate
.Puisqu'il semble être l'intérêt légitime de la propagation d'exception et ce qui est légèrement au moins un peu la question, voici ma suggestion:
std::thread
doit être considéré comme un dangereux primitive de construire par exemple, des abstractions de plus haut niveau. Ils sont doublement risqué exception-sage: si une exception se déclenche à l'intérieur du fil nous venons de lancer, tout explose, comme nous l'avons montré. Mais si une exception se déclenche dans le thread qui a lancé lestd::thread
nous peut éventuellement être en difficulté parce questd::thread
's destructeur exige que*this
être rejoint ou détaché (ou de manière équivalente, être pas-un-fil). Une violation de ces exigences de résultats dans... un appel àstd::terminate
!Un code de la carte des dangers de
std::thread
:Bien sûr, certains pourraient faire valoir que si nous nous contentons de
detach
ed chaque thread qui nous lancer, nous sommes en sécurité sur ce second point. Le problème c'est que dans certaines situations,join
est la chose la plus sensée à faire. La "naïve" de parallélisation de quicksort par exemple, nécessite d'attendre jusqu'à ce que les sous-tâches sont terminées. Dans ces situationsjoin
sert les primitives de synchronisation (rendez-vous).Heureusement pour nous, ceux de niveau supérieur abstractions je l'ai mentionné n'existe pas et venez avec la Bibliothèque Standard. Ils sont
std::async
,std::future
ainsi questd::packaged_task
,std::promise
etstd::exception_ptr
. L'équivalent, à l'exception-safe version de la ci-dessus:Et, en fait, au lieu d'appeler
get
dans le thread qui appelleasync
vous pouvez au lieu de passer la balle à un autre thread:std::thread
comme un dangereux primitive.