Comment tuer un thread individuel sous un processus sous Linux?

13

entrez la description de l'image ici

Ce sont les threads individuels du processus Packet Receiver. Existe-t-il un moyen de tuer un thread individuel? Linux fournit-il une commande spécifique qui peut tuer ou envoyer un signal d'arrêt à un thread particulier dans le cadre d'un processus?

Md. Kawsaruzzaman
la source
Quel est votre programme de réception de paquets? (Je ne l'ai pas sur mon bureau Debian) Veuillez en dire plus, peut-être fournir un lien. Modifiez donc votre question pour l'améliorer.
Basile Starynkevitch
1
Je pense que vous ne réalisez pas que le signal "stop" arrête un processus, quel que soit le thread auquel vous l'envoyez.
David Schwartz
1
Attachez avec GDB et tuez le fil , puis détachez.
Martin
1
@ Md.Kawsaruzzaman Cela ne fonctionnera tout simplement pas. Supposons, par exemple, que le thread se trouve au milieu de l'allocation de mémoire et détient le verrou sur l'allocateur de mémoire. Si vous arrêtez le fil, il ne relâchera jamais le verrou et, éventuellement, les autres fils s'arrêteront également. Quoi que vous essayiez de faire, ce n'est pas la façon de le faire. (Il se peut que vous vouliez arrêter le travail que le thread fait. Mais vous avez besoin de la coopération du processus pour le faire. S'il ne fournit aucun moyen de le faire, cela ne peut pas être fait.)
David Schwartz
1
Notez également que, dans votre capture d'écran, chaque "thread" a un PID distinct. Je ne suis pas sûr que vous puissiez même cibler des threads distincts, car les signaux pourraient être envoyés uniquement aux processus.
szalski

Réponses:

16

Il est généralement assez dangereux de tuer un thread individuel à partir d'un processus plus vaste. Ce fil pourrait:

  • Modifiez un état partagé avec d'autres threads qui pourraient être corrompus
  • Tenir un verrou qui ne se libère jamais, ce qui rend le verrou indéfiniment indisponible
  • ... ou un certain nombre d'autres choses qui pourraient entraîner le dysfonctionnement d'autres threads.

En général, en dehors de la gestion et de la synchronisation par l'application elle-même, la suppression de threads individuels n'est pas quelque chose de sensé.

Chris Down
la source
5
Ce n'est pas du tout utile. OP demande comment tuer un thread, pas s'il le devrait ou non.
Martin
Ce que je veux, c'est le processus pour tuer ou arrêter un thread particulier dans un but. Je suppose qu'en raison d'une erreur, notre récepteur est parfois automatiquement arrêté. Nous trouvons les causes à mesure que le programme est développé par notre propre R&D. Maintenant, le problème est qu'il peut y avoir une fermeture automatique de certains threads. Nous avons testé du côté du code et nous avons obtenu que le thread enfant soit indépendant mais du côté du serveur, nous obtenons toujours des threads, ce qui entraîne également l'arrêt total du processus.
Md. Kawsaruzzaman
12

Vous pouvez utiliser tgkill (2) ou tkilldans votre programme C (vous devrez utiliser syscall (2) ) mais vous ne le souhaitez pas . Depuis l'intérieur de votre programme, vous pouvez utiliser pthread_kill (3) - ce qui est rarement utile.

(Je ne sais pas exactement quel effet cela aurait tgkillou tkill- par exemple avec SIGKILLou SIGTERM- sur un fil)

La bibliothèque pthreads (7) utilise des éléments de bas niveau (y compris certains signaux (7) -s et futex (7) -s etc ...; voir aussi nptl (7) ) et si vous avez tué brutalement (avec tkillou tgkill) certains thread individuel, votre processus serait dans un mauvais état (donc comportement indéfini ) car certains invariants internes seraient cassés.

Alors étudiez la documentation de votre programme de récepteur de paquets et trouvez une autre manière. S'il s'agit d' un logiciel libre , étudiez son code source et améliorez-le.

Lisez attentivement le signal (7) et la sécurité du signal (7) . Les signaux sont destinés à être envoyés aux processus (par kill (2) ) et traités dans les threads.

Et dans la pratique, les signaux et les fils ne se marient pas bien. Lisez un didacticiel pthread .

Une astuce courante, lorsque vous codez un programme multi-thread (et que vous souhaitez gérer des signaux externes comme SIGTERM) est d'utiliser un pipe (7) pour votre propre processus et d' interroger (2) ce pipe dans un autre thread (vous pouvez également considérer Linux signalfd spécifique (2) ), avec un signal hander write (2) -ing un octet ou quelques-uns d'entre eux dans ce tuyau. Cette astuce bien connue est bien expliquée dans la documentation de Qt (et vous pouvez l'utiliser dans votre propre programme, même sans Qt).

Basile Starynkevitch
la source
4
La tgkillfonction ne fournit aucun moyen de terminer un thread. Il envoie un signal à un thread. Il est nommé "kill" car c'est la manière historique de tuer un processus et il ne peut pas être utilisé pour tuer un thread.
David Schwartz
Je suppose que l'envoi d'un SIGKILLà un fil de discussion lui nuit. Ou est-ce que cela tue toujours tout le processus? Et qu'en est-il SIGTERM? BTW, même si seul un thread est endommagé, mon point est que le processus est dans un état désastreux.
Basile Starynkevitch
5
Oui, les signaux SIGKILLet SIGTERMsont définis pour tuer ou terminer le processus. Cela est vrai quel que soit le fil qui les reçoit - ils signifient toujours la même chose. Terminer un fil sans la coopération étroite de son processus serait une connerie et probablement catastrophique pour le processus.
David Schwartz