BOOST :: thread quels problèmes y at-il à supprimer un thread joignable?

Quels sont les problèmes que l’on pourrait rencontrer en détruisant un pointeur de thread jointable? (c.-à-d. en appelant delete thread ) La référence de boost est un peu floue, des réponses plus précises sont souhaitables.

Voici un exemple spécifique:

Supposons qu’un thread enfant soit bloqué par un appel système non interruptible tel que read(0) sans que le clavier ne soit géré. Ainsi, appeler thread->interrupt() suivi d’un thread->try_join_for() laissera le thread joignable. Qu’est-ce qui devrait être fait?

D’après le guide de référence, il semble qu’il faille soit détacher le fil, soit laisser fuir le pointeur du fil. Ce qui se passe réellement lorsqu’un fil bloqué est détaché ou qu’un pointeur a été filtré sort du cadre de cette question.

Contexte:

Dans le boost::thread::~thread() référence est le verbiage suivant. En tant que “elle vend des coquillages au bord de la mer” du guide de référence BOOST, il faut lire trois ou quatre fois avant de pouvoir l’parsingr;

Détacher implicitement ou rejoindre un thread joinable () dans son destructeur pourrait rendre difficile le débogage des correctifs de correction (pour detach) ou de performance (pour rejoindre) rencontrés uniquement lorsqu’une exception est déclenchée. Ainsi, le programmeur doit s’assurer que le destructeur n’est jamais exécuté tant que le thread est encore joignable.

Le résumé de ceci (d’après ce que je peux dire) est que c’est une (mauvaise) idée (de) détruire (un) boost: 🙁 thread) pointeur (tant que) il (est) toujours (jointable). Et qui soulève l’exception mentionnée? Le fil d’enfant? Le destructeur?

Ça dépend. À l’origine, la mise en œuvre de Boost détacherait un fil non joint lors de la destruction. Cela a été changé depuis la version 1.52 pour correspondre au comportement de std::thread de C ++ 11: Détruire un thread non joint appelle maintenant std::terminate (qui plantera le programme par défaut). L’ancien comportement restra disponible en tant que fonctionnalité obsolète jusqu’à la version 1.56 et peut être activé en définissant l’ BOOST_THREAD_DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE préprocesseur BOOST_THREAD_DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE .

Pour votre exemple de fil bloqué dans un appel bloquant, le conseil doit donc être le suivant: ne le faites pas. Utilisez uniquement des appels d’E / S bloquants permettant de spécifier un délai d’expiration ou utilisez plutôt des E / S asynchrones. Vous devez être en mesure de signaler à un thread en attente d’E / S qu’il doit se terminer, sinon vous risquez un blocage lors de l’arrêt de votre programme.

Théoriquement, vous ne pouvez tout simplement pas rejoindre le thread (c’est-à-dire, détacher ou laisser fuir l’object boost::thread ). Cependant, cela cause généralement beaucoup d’autres maux de tête, car vous ne pouvez pas garantir que les ressources détenues par ce thread seront nettoyées correctement. Cela rend très difficile de raisonner sur le comportement d’un tel fil. Rappelez-vous qu’ISO-C ++ a décidé d’invoquer se terminate ici pour une raison.