web-dev-qa-db-fra.com

Pour pthread, How to kill child thread from the main thread

J'utilise pthread_create pour créer plusieurs threads enfants. À la fois, le thread principal veut tuer tous les threads enfants ou il y aura un segment falut. Quelle fonction dois-je utiliser pour terminer cela? J'ai recherché la réponse de google et obtenu la fonction comme pthread_kill. Mais je ne savais pas quel signal devrais-je envoyer au thread enfant pour les tuer. Mon environnement de course est RHEL 5.4 et le langage de programmation est C.

19
terry

Il est possible "d'annuler" un thread en utilisant pthread_cancel . Cependant, ce n'est généralement pas la meilleure pratique, bien que dans des circonstances extrêmes comme un SEGFAULT, cela puisse être considéré comme une approche raisonnable.

21
torak

En général, vous ne voulez pas vraiment tuer violemment un thread enfant, mais vous voulez plutôt lui demander de se terminer. De cette façon, vous pouvez être sûr que l'enfant arrête de fumer dans un endroit sûr et que toutes ses ressources sont nettoyées.

Je fais généralement cela avec un petit état partagé entre le parent et l'enfant pour permettre au parent de communiquer une "demande de sortie" à chaque enfant. Cela peut simplement être une valeur booléenne pour chaque enfant, protégé par un mutex. L'enfant vérifie cette valeur périodiquement (chaque itération de boucle, ou tout autre point de contrôle pratique que vous avez dans votre thread enfant). En voyant "quit_request" être vrai, le thread enfant nettoie et appelle pthread_exit.

Du côté parent, la routine "kill_child" ressemble à ceci:

acquire shared mutex
set quit_request to true 
pthread_join the child 

Pthread_join peut prendre un certain temps, selon la fréquence à laquelle l'enfant vérifie sa demande de sortie. Assurez-vous que votre conception peut gérer quel que soit le délai.

25
Bill Gribble

Vous devez envoyer SIG_TERM à chacun de vos threads, en utilisant

  int pthread_kill(pthread_t thread, int sig);

Un moyen rapide de se débarrasser de tous les threads (à part le principal) est de fork () et de continuer avec l'enfant.
Pas hyper propre ...

  if (fork()) exit(0); // deals also with -1...
7
Ring Ø

Vous pouvez utiliser une variable globale pour l'ensemble du programme.

int _fCloseThreads;

Définissez-le sur 1 lorsque vous souhaitez que les threads quittent l'exécution. Demandez aux threads de vérifier cette variable dans leur "boucle" et de quitter correctement lorsqu'elle est définie sur 1. Pas besoin de la protéger avec un mutex.

Vous devez attendre la fin des threads. Vous pouvez utiliser join. Une autre façon consiste à incrémenter un compteur lorsqu'un thread entre dans son processus de thread, puis à décrémenter le compteur à sa sortie. Le compteur devrait être une sorte de global. Utilisez gcc atomic ops sur le compteur. Le thread principal, après avoir défini fCloseThreads, peut attendre sur le compteur pour revenir à zéro en bouclant, en dormant et en vérifiant le nombre.

Enfin, vous pouvez extraire pthread_cleanup_Push et pop. Ils sont un modèle permettant à un thread d'annuler n'importe où dans son code (utilise un saut long), puis d'appeler une fonction de nettoyage final avant de quitter threadproc. Vous placez fondamentalement cleanup_Push en haut de votre threadproc et cleanup_pop en bas, créez une fonction de déroulement, puis à certains points d'annulation, un thread annulé par un appel à pthread_cancel () sautera longtemps vers threadproc et appellera la fonction de déroulement.

3
johnnycrash