Comment puis-je terminer un thread en C ++ 11?

Je n’ai pas besoin de terminer le thread correctement ou de le faire répondre à une commande “Terminer”. Je suis intéressé à terminer le thread avec force en utilisant C ++ 11 pur.

  1. Vous pouvez appeler std::terminate() partir de n’importe quel thread et le thread auquel vous faites référence se terminera avec force.

  2. Vous pouvez faire en sorte que ~thread() soit exécuté sur l’object du thread cible, sans un join() ni un detach() sur cet object. Cela aura le même effet que l’option 1.

  3. Vous pouvez concevoir une exception qui comporte un destructeur qui génère une exception. Ensuite, faites en sorte que le thread cible lance cette exception lorsqu’il doit être fermé de manière forcée. La partie délicate de celle-ci consiste à faire en sorte que le thread cible lance cette exception.

Les options 1 et 2 ne génèrent pas de ressources intra-processus, mais elles terminent chaque thread.

L’option 3 entraînera probablement une fuite de ressources, mais est partiellement coopérative en ce sens que le thread cible doit accepter de lancer l’exception.

Il n’y a pas de moyen portable dans C ++ 11 (que je connaisse) de tuer sans coopération un seul thread dans un programme multi-thread (c’est-à-dire sans tuer tous les threads). Il n’y avait aucune motivation pour concevoir une telle fonctionnalité.

Un std::thread peut avoir cette fonction membre:

 native_handle_type native_handle(); 

Vous pourrez peut-être l’utiliser pour appeler une fonction dépendante du système d’exploitation pour faire ce que vous voulez. Par exemple sur les systèmes d’exploitation d’Apple, cette fonction existe et native_handle_type est un pthread_t . Si vous réussissez, vous risquez de perdre des ressources.

La réponse de @Howard Hinnant est à la fois correcte et complète. Mais il peut être mal compris si la lecture est trop rapide, car std::terminate() (processus complet) a le même nom que le “terminateur” que @AlexanderVX avait en tête (1 thread).

Résumé: “Terminez 1 thread + avec force (le thread cible ne coopère pas) + C ++ 11 pur = Pas moyen.”

Cette question a en fait une nature plus profonde et une bonne compréhension des concepts de multithreading en général vous donnera un aperçu de ce sujet. En fait, il n’existe aucun langage ou système d’exploitation qui vous permette de ne pas utiliser les terminaisons de threads asynchrones sans avertissement. Et tous ces environnements d’exécution conseillent fortement les développeurs ou exigent même la création d’applications multithreading sur la base de la terminaison de threads coopérative ou synchrone. La raison de ces décisions et conseils communs est que tout est construit sur la base du même modèle multithreading général.

Comparons les concepts de multitraitement et de multithreading pour mieux comprendre les avantages et les limites du second.

Le multitraitement suppose la division de l’environnement d’exécution complet en un ensemble de processus complètement isolés contrôlés par le système d’exploitation. Processus intègre et isole l’état de l’environnement d’exécution, y compris la mémoire locale du processus et des données qu’il contient, ainsi que toutes les ressources système telles que les fichiers, les sockets, les objects de synchronisation. L’isolement est une caractéristique essentielle du processus, car il limite la propagation des défauts par les limites du processus. En d’autres termes, aucun processus ne peut affecter la cohérence d’un autre processus du système. La même chose est vraie pour le comportement du processus, mais de manière moins restreinte et plus floue. Dans un tel environnement, tout processus peut être détruit à tout moment “arbitraire”, car chaque processus est isolé. Deuxièmement, le système d’exploitation connaît parfaitement toutes les ressources utilisées par les processus et peut les libérer tous sans fuites. par OS pas vraiment dans un moment arbitraire, mais dans le nombre de points bien définis où l’état du processus est bien connu.

En revanche, le multithreading suppose d’exécuter plusieurs threads dans le même processus. Mais tous ces threads partagent la même boîte d’isolement et il n’y a aucun contrôle du système d’exploitation de l’état interne du processus. En conséquence, tout thread est capable de changer l’état du processus global et de le corrompre. Au même moment, les points sur lesquels l’état du thread est connu pour être sûr de tuer un thread dépend entièrement de la logique de l’application et ne sont connus ni du système d’exploitation ni de l’exécution du langage de programmation. En conséquence, la terminaison de thread à un moment arbitraire signifie la tuer à un point arbitraire de son chemin d’exécution et peut facilement conduire à la corruption des données, à la mémoire et aux fuites, aux threads et aux autres primitives de synchronisation intra-process. état fermé empêchant les autres threads de progresser.

De ce fait, l’approche habituelle consiste à forcer les développeurs à mettre en œuvre une terminaison de thread synchrone ou coopérative, où le thread peut demander une autre terminaison de thread et un autre thread au point bien défini peut vérifier cette requête et démarrer la procédure d’arrêt avec la libération de toutes les ressources globales du système et des ressources au niveau des processus locaux de manière sûre et cohérente.

Conseils d’utilisation de la fonction dépendante du système d’exploitation pour terminer le thread C ++:

  1. std::thread::native_handle() peut uniquement obtenir le type de std::thread::native_handle() natif valide du thread avant d’appeler join() ou detach() . Après cela, native_handle() retourne 0 – pthread_cancel() sera coredump.

  2. Pour appeler efficacement la fonction de terminaison de thread native (par exemple pthread_cancel) , vous devez enregistrer le descripteur natif avant d’appeler std::thread::join() ou std::thread::detach() . Pour que votre terminateur natif ait toujours un handle natif valide à utiliser.

Plus d’explications s’il vous plaît se référer à: http://bo-yang.github.io/2017/11/19/cpp-kill-detached-thread .