Alternative Möglichkeit, einen Zombie-Prozess zu beenden

19

Ich habe gerade einige Zombie-Prozesse auf CentOS 6.8 (Final) bemerkt, habe versucht, sie zu töten, aber sie sind immer noch da:

[root@host user]# ps -ef | grep git
tomcat     746     1  0 Jul18 ?        00:00:00 git clone https://github.com/angular/bower-angular.git -b v1.3.20 --progress . --depth 1
tomcat     747   746  0 Jul18 ?        00:00:00 [git-remote-http] <defunct>
root     20776 20669  0 09:03 pts/3    00:00:00 grep git
tomcat   29970     1  0 Jul18 ?        00:00:00 git clone https://github.com/components/jqueryui.git -b 1.12.0 --progress . --depth 1
tomcat   29971 29970  0 Jul18 ?        00:00:00 [git-remote-http] <defunct>

[root@host user]# kill 746 747 29970 29971

[root@host user]# ps -ef | grep git
tomcat     746     1  0 Jul18 ?        00:00:00 git clone https://github.com/angular/bower-angular.git -b v1.3.20 --progress . --depth 1
tomcat     747   746  0 Jul18 ?        00:00:00 [git-remote-http] <defunct>
root     21525 20669  0 09:26 pts/3    00:00:00 grep git
tomcat   29970     1  0 Jul18 ?        00:00:00 git clone https://github.com/components/jqueryui.git -b 1.12.0 --progress . --depth 1
tomcat   29971 29970  0 Jul18 ?        00:00:00 [git-remote-http] <defunct>

Wie Sie sehen können, laufen sie zwei Monate lang, und wenn sie nicht schädlich sind, würde ich sie auch loswerden. Gibt es eine alternative Möglichkeit, einen Zombie zu töten?

lese
quelle
1
haben Sie versucht kill -9?
Ipor Sircer
7
Nur 747und 29971sind Zombie-Prozesse. Die anderen sind vielleicht eingesperrt, aber noch nicht tot.
Roaima
Scheint, Sie haben einen Fehler in einem Code, der auf Tomcat ausgeführt wird ...
Boris the Spider

Antworten:

8

Wie von Heemayl erwähnt, kann man einen Zombie nicht wirklich töten. Es ist schon [un] tot ...

Das Problem, mit dem Sie konfrontiert sind, scheint jedoch ein Problem mit dem git cloneBefehl zu sein. Es bleibt irgendwie hängen. Vermutlich mal raus oder scheitert es auf andere Weise? Oft ist es wegen einiger I / O , dass ein Prozess auf den Punkt stecken bleibt , wo ein SIGTERMund SIGINTwird nicht funktionieren.

Um es zu beenden, möchten Sie in diesem Fall die -9Befehlszeilenoption verwenden. Dies bedeutet, das SIGKILLSignal zu senden . Sie können tatsächlich auch verwenden -KILL.

[root@host user]# kill -KILL 746 29970

Verwenden Sie die Befehlszeilenoption list, um eine Liste der verfügbaren Signale abzurufen.

[root@host user]# kill -l

Dies zeigt Ihnen die Nummern und Namen (und Sie werden sehen, dass # 9 SIGKILL sagt.)

Alexis Wilke
quelle
1
Eigentlich kill -KILLwar der einzige Befehl in der Lage, diese Prozesse zu schließen, aus diesem Grund werde ich @Alexis Wilke Antwort akzeptieren. Aber sicherlich möchte ich mich bei @heemayl für die schnelle, weise und sehr informative Antwort +1 bedanken. Vielen Dank an alle
Lese
39

Du kannst keinen Zombie (Prozess) töten, er ist bereits tot. Es wartet nur darauf, dass der übergeordnete Prozess wait(2)den Beendigungsstatus abruft. Es wird keine andere Ressource auf dem System beansprucht als ein Prozesstabelleneintrag.

Sie können SIGCHLDdem Elternteil mitteilen, dass eines der untergeordneten Elemente beendet wurde (dh, Sie können das Kind auffordern, den Beendigungsstatus zu erfassen). Dieses Signal kann ignoriert werden (dies ist die Standardeinstellung):

kill -CHLD <PPID>

(Ersetzen Sie <PPID>durch die tatsächliche PID des übergeordneten Elements.)

Oder Sie können den übergeordneten Prozess beenden, damit init(PID 1) den Zombie-Prozess erbt und ordnungsgemäß erntet (es ist eine der initHauptaufgaben, verwaiste Prozesse zu erben und wait(2)regelmäßig auszuführen ). Es wird jedoch nicht empfohlen, die Eltern zu töten. Im Allgemeinen weist die Erstellung von Zombie-Prozessen auf Programmierprobleme hin, und Sie sollten versuchen, dies zu beheben oder zu melden.

heemayl
quelle
8
Sie können SIGCHLD zu seinen Eltern schicken sie wissen zu lassen, dass man , wenn es Kinder beendet hat (dh es fordert Exit - Status zu sammeln Kinder), kann dieses Signal ignoriert werden (default) Das Problem dabei ist , dass , wenn ein Prozess ignoriert SIGCHLD, kein Zombie erstellt werden würde. Wenn es also nicht ignoriert SIGCHLDwird und Zombies nicht geerntet werden, ist der Prozess entweder fehlerhaft oder kümmert sich nicht um Zombiekinder. Angesichts der Tatsache, dass es sich um einen Prozess handelt git clone ..., bei dem es um einen (hoffentlich) kurzlebigen Prozess geht, der seine Arbeit erledigt und dann beendet
Andrew Henle
1
@AndrewHenle: Während das meistens zutrifft, ist die Standardaktion ( SIG_DFL) für SIGCHILDauch, es zu ignorieren, aber in diesem Fall werden Zombies mit Sicherheit nicht automatisch geerntet.
R ..
@R Obwohl dies meistens zutrifft, besteht die Standardaktion ( SIG_DFL) für SIGCHILDauch darin, es zu ignorieren, aber in diesem Fall werden Zombies höchstwahrscheinlich nicht automatisch geerntet. Ich bin nicht sicher, worauf Sie sich beziehen. Beziehen Sie sich auf die Prozesse, die in der Frage nicht erfasst werden? Ich sehe nicht, wie das Senden SIGCHLDan einen Prozess, für den der SIGCHLDHandler SIG_IGN(explizit oder standardmäßig) festgelegt ist, dazu führt, dass dieser Prozess Zombies erntet.
Andrew Henle
1
@ AndrewHenle, Senden eines SIGCHLDkann diesmal funktionieren . Das letzte Mal, als es möglicherweise das Signal verpasst hat oder zwei Kinder gleichzeitig gestorben sind und der Code nicht intelligent genug ist, um mit beiden Todesfällen gleichzeitig umzugehen.
Alexis Wilke
Es kann nicht schaden, aber ich würde nicht darauf setzen, dass es funktioniert.
Barmar
2

um nach Zombieprozessen zu suchen:

ps aux | grep -w Z | grep -v grep

ps -eo stat,ppid | grep -w Z

Um den Zombie-Prozess zu beenden, müssen die übergeordneten IDs beendet werden, dh PPID:

kill PPID1 PPID2

kill $(ps -eo stat,ppid|grep -w Z|awk '{print $2}'|tr "\n" " ")
user218243
quelle
0

Wenn ein übergeordneter Prozess stirbt, werden alle Zombie-Prozesse bereinigt. Töte nicht den übergeordneten Prozess, nur um den Zombie-Prozess zu bereinigen. Es wird wieder kommen, wenn Sie Ihr Programm erneut ausführen. Beheben Sie Ihr Programm, indem Sie den Systemaufruf "wait ()" oder "waitpid ()" ordnungsgemäß aufrufen.

Sumanth S
quelle