Was ist ein <defunct> -Prozess und warum wird er nicht getötet?


180

Der Chrome-Browser <defunct>reagierte nicht und ich habe versucht, ihn zu beenden, aber statt zu verschwinden, hatte der Prozess seine Berechtigung und wurde nicht beendet:

Bildbeschreibung hier eingeben

Was ist <defunct>für einen Prozess und warum wird er nicht getötet?


3
Die akzeptierte Antwort erwähnt, dass " kill -9 PIDnicht funktioniert". Es ist teilweise wahr: In Wirklichkeit wird KEIN Kill funktionieren. Außerdem sollte -9 als letzter Ausweg verwendet werden. In 99% der Fälle wird ein Standard-Kill des übergeordneten Prozesses ihn töten UND alle Kinder ernten. Ein "Standard-Kill" ist ein SIGTERM (-15). Ich ermutige Fans der -9 (SIGKILL), stackoverflow.com/questions/690415/…
Mike S

Antworten:


172

In Ihrer Ausgabe sehen wir ein "defunct", was bedeutet, dass der Prozess entweder seine Aufgabe abgeschlossen hat oder beschädigt oder beendet wurde, seine untergeordneten Prozesse jedoch noch ausgeführt werden oder dieser übergeordnete Prozess seinen untergeordneten Prozess überwacht. Um diesen Prozess abzubrechen, funktioniert kill -9 PID nicht. Sie können versuchen, sie mit diesem Befehl zu töten, dies wird jedoch immer wieder angezeigt.

Bestimmen Sie, welcher Prozess der übergeordnete Prozess dieses nicht mehr vorhandenen Prozesses ist, und beenden Sie ihn. Um dies zu erfahren, führen Sie den Befehl aus:

ps -ef | grep defunct

UID          PID     PPID       C    STIME      TTY          TIME              CMD
1000       637      27872      0   Oct12      ?        00:00:04 [chrome] <defunct>
1000      1808      1777       0    Oct04     ?        00:00:00 [zeitgeist-datah] <defunct>

Vergewissern Sie kill -9 637 27872sich dann, dass der Prozess nicht mehr ausgeführt wird ps -ef | grep defunct.


13
Sie können "nicht mehr funktionierende" Prozesse nicht beenden. Sie können das Löschen des Eintrags in einer Prozesstabelle nur beschleunigen, indem Sie den übergeordneten Eintrag beenden.
jfs

57
Was ist, wenn die ppid 1( init) ist? Angenommen, ich muss nur warten?
Luc

7
Um den Kill zu automatisieren, können Sie dies auch tun (möglicherweise müssen Sie ändern, welche Bytes Sie aus der Ausgabe ps -ef | grep defunct | grep -v grep | cut -b8-20 | xargs kill -9
entfernen

3
@ Waren Danke. Sie können das auch etwas kürzer und (imo) einfacher machen, indem Sie kein zweites Grep machen. Ändern Sie einfach das erste Grep auf grep [d]efunctoder ähnliches und es passt nicht zu sich selbst.
Thor84no

4
@warren Du kannst einen nicht mehr existierenden Prozess nicht beenden - auch nicht mit einem SIGKILL. Außerdem benutzt du kill -9 ziemlich wahllos. Siehe stackoverflow.com/questions/690415/… . Wenn Sie nicht mehr existierende Kinder töten wollen, könnten Sie versuchen: parents_of_dead_kids=$(ps -ef | grep [d]efunct | awk '{print $3}' | sort | uniq | egrep -v '^1$'); echo "$parents_of_dead_kids" | xargs kill. Führen Sie das Skript nach ca. 30 Sekunden erneut aus, kill -9wenn Sie dies wünschen. (Beachten Sie, dass ich ausdrücklich das Töten von verbiete Init)
Mike S

60

Manual page ps (1) sagt :

Markierte Prozesse <defunct>sind tote Prozesse (sogenannte "Zombies" ), die verbleiben, weil ihre Eltern sie nicht richtig zerstört haben. Diese Prozesse werden zerstört, init(8)wenn der übergeordnete Prozess beendet wird.

Sie können es nicht töten, weil es bereits tot ist. Übrig bleibt nur ein Eintrag in der Prozesstabelle :

Unter Unix- und Unix-ähnlichen Computer-Betriebssystemen ist ein Zombie-Prozess oder ein nicht mehr funktionierender Prozess ein Prozess, dessen Ausführung abgeschlossen wurde, der jedoch noch einen Eintrag in der Prozesstabelle enthält. Dieser Eintrag wird weiterhin benötigt, damit der übergeordnete Prozess den Exit-Status des untergeordneten Prozesses lesen kann.

Es schadet nicht, solche Prozesse zuzulassen, es sei denn, es gibt viele davon. Der Zombie wird schließlich von seinem Elternteil (durch einen Anruf wait(2)) geerntet . Wenn das ursprüngliche übergeordnete Element es vor seinem eigenen Beenden nicht geerntet hat, führt initprocess ( pid == 1) dies zu einem späteren Zeitpunkt aus. Zombie-Prozess ist nur:

Ein Prozess, der beendet wurde und gelöscht wird, wenn sein Beendigungsstatus einem anderen Prozess gemeldet wurde, der darauf wartet, dass dieser Prozess beendet wird.


1

Vielen Dank, Mike S. Wir haben Ihre Linie genommen und ein Skript geschrieben, das nicht mehr funktionierende Prozesse beendet, deren übergeordnetes Element in.telnetd ist. Wir wollten nicht, dass ein übergeordneter Prozess beendet wird. Wir wissen nur, dass telnetd ein Problem verursacht, und führen es bei Bedarf mehrmals aus, um mehrere Prozesse zu beenden.

# egrep -v '^1$ = Make sure the process is not the init process.
# awk '{print $3}' = Print the parent process.

first_parent_of_first_dead_kid=$(ps -ef | grep [d]efunct | awk '{print $3}' | head -n1 | egrep -v '^1$')
echo "$first_parent_of_first_dead_kid"

# If the first parent of the first dead kid is in.telnetd, then kill it.
if ps -ef | grep $first_parent_of_first_dead_kid | grep in.telnetd;then
        echo "We have a defunct process whose parent process is in.telnetd" | logger -t KILL-DEFUNCT-TELNET
        echo "killing $first_parent_of_first_dead_kid" | logger -t KILL-DEFUNCT-TELNET
        kill $first_parent_of_first_dead_kid 2>&1 | logger -t KILL-DEFUNCT-TELNET
fi

1

auf Paddingtons Antwort erweitern ..

In Ihrer Ausgabe sehen wir einen Defekt , was bedeutet, dass dieser untergeordnete Prozess entweder seine Aufgabe abgeschlossen hat oder beschädigt oder getötet wurde. Der übergeordnete Prozess läuft noch und das tote Kind ist ihm nicht aufgefallen.

kill -9 PID wird nicht funktionieren (bereits tot).

Führen Sie den folgenden Befehl aus, um das übergeordnete Element dieses untergeordneten Prozesses zu ermitteln:

ps -ef | grep defunct

 UID  PID **PPID** C STIME TTY TIME     CMD
 1000 637  27872   0 Oct12 ?   00:00:04 [chrome] <defunct>

Sehen Sie, wer der Elternteil ist: ps ax | grep 27872

Wenn du willst, kannst du die Eltern töten, und der Verstorbene verschwindet. kill -9 27872

Weitere technische Gründe finden Sie in der Antwort von JF Sebastian.


1

Als Ergänzung zu @ Paddingtons Antwort habe ich diese Funktion zur schnellen Überprüfung zu meinem bashrc hinzugefügt:

defunct(){
    echo "Children:"
    ps -ef | head -n1
    ps -ef | grep defunct
    echo "------------------------------"
    echo "Parents:"
    ppids="$(ps -ef | grep defunct | awk '{ print $3 }')"
    echo "$ppids" | while read ppid; do
        ps -A | grep "$ppid"
    done
}

Es gibt etwas aus wie:

Kinder:
UID PID PPID C STIME TTY TIME CMD
user 25707 25697 0 Feb26 pts / 0 00:00:00 [sh] 
user 30381 29915 0 11:46 pts / 7 00:00:00 grep verstorben
------------------------------
Eltern:
25697 Punkte / 0 00:00:00 Uhr
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.