Wie kann ich einen bestimmten Thread eines Prozesses beenden?

21
$ ps -e -T | grep myp | grep -v grep
  797   797 ?        00:00:00 myp
  797   798 ?        00:00:00 myp
  797   799 ?        00:00:00 myp
  797   800 ?        00:00:00 myp

Dies zeigt den Prozess mypmit PID = 797 und vier Threads mit unterschiedlichen SPIDs.

Wie kann ich einen bestimmten Thread des Prozesses beenden, ohne den gesamten Prozess zu beenden? Ich verstehe, dass es in einigen Fällen möglicherweise überhaupt nicht möglich ist, wenn schwerwiegende Abhängigkeiten von diesem bestimmten Thread bestehen. Aber ist das auf jeden Fall möglich? Ist ja wie

Ich habe es versucht kill 799und der Prozess selbst wurde abgebrochen. Ich bin mir nicht sicher, ob dies daran lag, dass Abhängigkeiten mypfehlgeschlagen sind, ohne dass der Prozess ausgeführt wurde, 800oder dass kill einfach nicht in der Lage ist, einzelne Prozesse zu beenden.

Laser
quelle

Antworten:

26

Threads sind ein wesentlicher Bestandteil des Prozesses und können außerhalb nicht getötet werden. Dort ist der Funktion pthread_kill , die jedoch nur im Kontext des Threads selbst angewendet wird . Aus den Dokumenten unter dem Link:

Beachten Sie, dass pthread_kill () nur bewirkt, dass das Signal im Kontext des angegebenen Threads verarbeitet wird. Die Signalaktion (Beenden oder Stoppen) wirkt sich auf den gesamten Prozess aus.

gvkv
quelle
+1. nur um hier hinzuzufügen. Innerhalb des Prozesses können Sie mit pthread_kill () Signale an einzelne Threads senden. Möglicherweise können Sie einen Signal-Handler hinzufügen, der dies erledigt.
Hemant
@hemant: Angenommen, MS Word verwendet einen separaten Thread für die Rechtschreibprüfung. Das Beenden dieses Threads sollte das Ganze nicht zum Erliegen bringen, es sei denn, es ist so konzipiert. Warum kann der Prozess in solchen Situationen nicht ohne diesen Thread existieren?
Lazer
1
Nun, ich nehme an, Sie könnten ein Threading-Modell so entwerfen, dass es unabhängig von einem übergeordneten Prozess ist, es aber externen Prozessen ermöglicht, prozessinterne Threads abzutöten. Ich glaube, jeder Systementwickler würde sich bereitwillig unterwerfen. Ohne solche Kopfschmerzen ist das Einfädeln schwierig genug. Das Killen eines Threads von innen ist kein Problem, da die Arbeit von dem übergeordneten Prozess ausgeführt wird, der dafür verantwortlich ist, wenn Probleme auftreten und beendet werden können - automatisch oder auf andere Weise.
gvkv
"es sei denn, es ist so konzipiert": Der Hauptgrund für die Verwendung von Threads ist genau, damit Sie Ressourcen gemeinsam nutzen können. Es ist eher so, als würde man ein halbes Haus umstoßen.
pjc50
2
@ Lazer, ein Thread kann die Rechtschreibung nicht gleichzeitig überprüfen, wenn ein anderer Thread den Text aktualisiert, weil Sie tippen. Aus diesem Grund muss ein Thread, der die Rechtschreibprüfung im Hintergrund durchführt, eine Sperre aktivieren, um zu verhindern, dass der andere Thread den Text ändert. Anschließend müssen Sie eine Kopie einiger Wörter erstellen, die Sperre aufheben und die kopierten Wörter in überprüfen Hintergrund. Wenn Sie es töteten, während es die Sperre hielt, hingen Sie den anderen Thread, sobald Sie versuchten, zu tippen. Multithread-Anwendungen sind voller Abhängigkeiten.
Psusi
6

Die kanonische Antwort auf diese Frage lautet: Mit der Kooperation des Prozesses, durch welchen Mechanismus auch immer. Ohne die Mitarbeit des Prozesses ist es unmöglich. Dass der Prozess aus Threads besteht, ist ein internes Detail des Prozesses, das absichtlich nicht außerhalb des Prozesses verfügbar gemacht wird.

David Schwartz
quelle
Und was ist mit dem Senden der anderen Signale von der Kommandozeile?
Yucer
@yucer Ich bin nicht sicher, ob ich verstehe, was Sie fragen.
David Schwartz
Ich meine, ein anderes Signal aus der mit "kill -l" angezeigten Liste zu senden. Ich suche nach einer Möglichkeit, einem bestimmten Thread zu befehlen, den Stack-Trace zu sichern, um zu sehen, was er tut.
Yucer
@yucer Das wird plattformspezifisch sein. Einige bieten eine Möglichkeit, einen bestimmten Thread zum Speichern des Stacks zu befehlen. Persönlich finde ich es einfacher, einfach ein Skript zu verwenden, um einen Debugger (wie gdb) an den Prozess anzuhängen , alle Threads anzuweisen, den Stack zu sichern und dann die Verbindung zu trennen.
David Schwartz
1

Neben der Antwort von @ gkv können Sie einen Blick auf die Funktion werfen pthread_cancel(3), die Teil von ist <pthread.h>. Von der Manpage:

Die Funktion pthread_cancel () sendet eine Abbruchanforderung an den Thread-Thread. Ob und wann der Ziel-Thread auf die Abbruchanforderung reagiert, hängt von zwei Attributen ab, die von diesem Thread gesteuert werden: dem Status und dem Typ der Abbruchfähigkeit.

Ivan P
quelle
1

Sie können tgkill () nützlich finden. Es ist Linux-spezifisch, wie in der Manpage erwähnt.

tgkill () sendet das Signal sig an den Thread mit der Thread-ID tid in der Thread-Gruppe tgid. (Im Gegensatz dazu kann kill (2) nur verwendet werden, um ein Signal an einen Prozess (dh eine Thread-Gruppe) als Ganzes zu senden, und das Signal wird an einen beliebigen Thread innerhalb dieses Prozesses geliefert.)

Amit
quelle
Hiermit wird nicht die Frage beantwortet, wie ein Thread beendet werden soll, und nicht, wie ein Signal an einen Thread gesendet werden soll.
David Schwartz