Antworten:
kill -9
( SIGKILL ) funktioniert immer, vorausgesetzt, Sie haben die Berechtigung, den Vorgang abzubrechen. Grundsätzlich muss der Prozess entweder von Ihnen gestartet werden und nicht setuid oder setgid sein, oder Sie müssen root sein. Es gibt eine Ausnahme: Selbst Root kann kein schwerwiegendes Signal an PID 1 (den init
Prozess) senden .
Es kill -9
ist jedoch nicht garantiert, dass es sofort funktioniert . Alle Signale, einschließlich SIGKILL, werden asynchron geliefert: Der Kernel kann einige Zeit benötigen, um sie zu liefern. Normalerweise dauert die Signalübertragung höchstens einige Mikrosekunden, genau so lange, bis das Ziel eine Zeitscheibe abgerufen hat. Wenn das Ziel das Signal blockiert hat , wird das Signal in die Warteschlange gestellt, bis das Ziel es entsperrt.
Normalerweise können Prozesse SIGKILL nicht blockieren. Aber Kernel - Code kann und Prozesse Ausführen von Code - Kernel , wenn sie anrufen Systemaufrufe . Kernel-Code blockiert alle Signale, wenn der Systemaufruf unterbrochen wird, was zu einer schlecht geformten Datenstruktur irgendwo im Kernel oder allgemeiner zu einer Verletzung einer Kernel-Invariante führen würde. Wenn ein Systemaufruf (aufgrund eines Fehlers oder eines fehlerhaften Designs) auf unbestimmte Zeit blockiert wird, kann der Prozess möglicherweise nicht abgebrochen werden. (Der Vorgang wird jedoch abgebrochen, wenn der Systemaufruf jemals abgeschlossen wird.)
Ein in einem Systemaufruf blockierter Prozess befindet sich im unterbrechungsfreien Ruhezustand . Der Befehl ps
oder top
wird (bei den meisten Unices) den Status anzeigen D
(ursprünglich für " d isk", glaube ich).
Ein klassischer Fall eines langen unterbrechungsfreien Ruhezustands ist der Zugriff auf Dateien über NFS, wenn der Server nicht antwortet. Moderne Implementierungen neigen dazu, keinen unterbrechungsfreien Schlaf zu erzwingen (z. B. unter Linux ermöglicht die intr
Mount-Option, dass ein Signal den Zugriff auf NFS-Dateien unterbricht).
Es kann vorkommen , dass in der oder -Ausgabe Einträge angezeigt werden, die mit Z
(oder H
unter Linux, ich weiß nicht, was der Unterschied ist) markiert sind . Hierbei handelt es sich technisch gesehen nicht um Prozesse, sondern um Zombie-Prozesse, bei denen es sich lediglich um einen Eintrag in der Prozesstabelle handelt, der so verwaltet wird, dass der übergeordnete Prozess über den Tod seines Kindes benachrichtigt werden kann. Sie verschwinden, wenn der übergeordnete Prozess aufpasst (oder stirbt).ps
top
man 5 nfs
: "Die Option intr
/ nointr
mount ist nach Kernel 2.6.25 veraltet. Nur SIGKILL kann einen ausstehenden NFS-Vorgang auf diesen Kerneln unterbrechen. Wenn diese Option angegeben ist, wird sie ignoriert, um die Abwärtskompatibilität mit älteren Kerneln zu gewährleisten."
sshfs
Prozess beenden (und ebenso mit jedem anderen FUSE-Dateisystem: Sie können die Bereitstellung auf diese Weise immer erzwingen).
Manchmal existiert ein Prozess, der nicht beendet werden kann, weil:
top
wird Z signalisierttop
wird durch D. signalisiertEs hört sich so an, als hättest du einen Zombie-Prozess . Dies ist harmlos: Die einzige Ressource, die ein Zombie-Prozess verbraucht, ist ein Eintrag in der Prozesstabelle. Es verschwindet, wenn der Elternprozess stirbt oder auf den Tod seines Kindes reagiert.
Mit top
dem folgenden Befehl können Sie feststellen, ob es sich bei dem Prozess um einen Zombie handelt :
ps aux | awk '$8=="Z" {print $2}'
ps
. Wer kann sicher sein, dass das erforderliche Feld immer das 8. mit allen Implementierungen von ps
in allen Unices sein wird?
Überprüfen Sie Ihre /var/log/kern.log
und /var/log/dmesg
(oder Äquivalente) auf Hinweise. Nach meiner Erfahrung ist mir dies nur passiert, wenn die Netzwerkverbindung eines NFS-Mount plötzlich unterbrochen wurde oder ein Gerätetreiber abstürzte. Könnte passieren, wenn auch eine Festplatte ausfällt, glaube ich.
Mit können Sie lsof
sehen, welche Gerätedateien der Prozess geöffnet hat.
kill -9
Normalerweise hat es nicht funktioniert, auch nach 60 Minuten Wartezeit. Die einzige Lösung war ein Neustart.
Wenn die Antworten von @ Maciej und @ Gilles Ihr Problem nicht lösen und Sie den Vorgang nicht erkennen (und die Frage, was es mit Ihrer Distribution ist, gibt keine Antwort). Suchen Sie nach Rootkits und anderen Zeichen, deren Eigentümer Sie sind . Ein Rootkit kann mehr als verhindern, dass Sie den Prozess beenden. Tatsächlich sind viele in der Lage, Sie daran zu hindern, sie zu sehen. Wenn sie jedoch vergessen, ein kleines Programm zu ändern, werden sie möglicherweise entdeckt (z. B. geändert top
, aber nicht htop
). Höchstwahrscheinlich ist dies nicht der Fall, aber besser als Nachsicht.
Töten bedeutet eigentlich, ein Signal zu senden. Sie können mehrere Signale senden. kill -9 ist ein besonderes Signal.
Beim Senden eines Signals wird es von der Anwendung verarbeitet. wenn nicht, befasst sich der Kernel damit. So können Sie ein Signal in Ihrer Anwendung abfangen.
Aber ich sagte, Kill -9 sei etwas Besonderes. Das Besondere ist, dass die Anwendung es nicht versteht. Es geht direkt zum Kernel, der die Anwendung dann bei der ersten möglichen Gelegenheit wirklich beendet. mit anderen Worten tötet es tot
kill -15 sendet das Signal SIGTERM, das für SIGNAL TERMINATE steht, mit anderen Worten, es weist die Anwendung an, das Programm zu beenden. Dies ist die benutzerfreundliche Methode, um einer Anwendung mitzuteilen, dass sie heruntergefahren werden muss. Wenn die Anwendung jedoch nicht reagiert, wird sie mit kill -9 beendet.
Wenn kill -9 nicht funktioniert, bedeutet dies wahrscheinlich, dass Ihr Kernel aus dem Ruder gelaufen ist. Ein Neustart ist in Ordnung. Ich kann mich nicht erinnern, dass das jemals passiert ist.
Überprüfen Sie zunächst, ob es sich um einen Zombie-Prozess handelt (was sehr gut möglich ist):
ps -Al
Sie werden etwas sehen wie:
0 Z 1000 24589 1 0 80 0 - 0 exit ? 00:00:00 soffice.bin <defunct>
(Beachten Sie das "Z" auf der linken Seite)
Wenn die 5. Spalte nicht 1 ist, hat sie einen übergeordneten Prozess. Versuchen Sie, diese übergeordnete Prozess-ID zu beenden .
Wenn seine PPID = 1 ist, TÖTEN SIE ES NICHT !! , überlegen Sie, welche anderen Geräte oder Prozesse damit zusammenhängen könnten.
Wenn Sie beispielsweise ein bereitgestelltes Gerät oder Samba verwendet haben, versuchen Sie, es zu deaktivieren. Das kann den Zombie-Prozess auslösen.
ANMERKUNG : Wenn ps -Al
(oder top
) ein "D" anstelle von "Z" anzeigt, kann dies mit der Remote-Bereitstellung (wie NFS) zusammenhängen. Nach meiner Erfahrung ist ein Neustart der einzige Weg, um dorthin zu gelangen. Sie können jedoch auch die anderen Antworten überprüfen, die diesen Fall ausführlicher behandeln.
Wie andere bereits erwähnt haben, kann ein Prozess im unterbrechungsfreien Schlaf nicht sofort (oder in einigen Fällen überhaupt) beendet werden. Es ist erwähnenswert, dass ein weiterer Prozessstatus, TASK_KILLABLE, hinzugefügt wurde, um dieses Problem in bestimmten Szenarien zu lösen, insbesondere in dem allgemeinen Fall, dass der Prozess auf NFS wartet. Siehe http://lwn.net/Articles/288056/
Leider glaube ich nicht, dass dies irgendwo im Kernel verwendet wird, außer in NFS.
ls
Prozess zu sshfs
beenden, der auf einen Mount zugreift , wenn der Remote-Server nicht erreichbar ist. Gibt es eine Lösung für FUSE oder sshfs, die ich in Zukunft verwenden könnte, um solche Situationen zu vermeiden? 2.6.30 Kernel
Hat ein kleines Drehbuch geschrieben, das mir sehr geholfen hat, es anzuschauen!
Sie können damit jeden Prozess mit einem bestimmten Namen im Pfad beenden (beachten Sie dies !!) oder Sie können jeden Prozess eines bestimmten Benutzers mit dem Parameter "-u Benutzername" beenden.
#!/bin/bash
if [ "$1" == "-u" ] ; then\n
PID=`grep "$2" /etc/passwd | cut -d ":" -f3`
processes=`ps aux | grep "$PID" | egrep -v "PID|ps \-au|killbyname|grep" | awk '{ print $2}'`
echo "############# Killing all processes of user: $2 ############################"
else
echo "############# Killing processes by name: $1 ############################"
processes=`ps aux | grep "$1" | egrep -v "killbyname|grep" | awk '{ print $2}' `
fi
for process in $processes ; do
# "command" stores the entire commandline of the process that will be killed
#it may be useful to show it but in some cases it is counter-productive
#command=`ps aux | grep $process | egrep -v "grep" | awk '{ print $2 }'`
echo "Killing process: $process"
echo ""
kill -9 $process
done
Es gibt Fälle, in denen, selbst wenn Sie einen kill -9-Befehl an einen Prozess senden, diese pid beendet wird, der Prozess jedoch automatisch neu gestartet wird (wenn Sie es beispielsweise mit versuchen gnome-panel
, wird er neu gestartet): Könnte dies hier der Fall sein?
von hier ursprünglich :
Überprüfen Sie, ob Strace etwas zeigt
strace -p <PID>
versuche, mit gdb an den Prozess anzuhängen
gdb <path to binary> <PID>
Wenn der Prozess mit einem Gerät interagiert hat, für das Sie die Bereitstellung aufheben, das Kernelmodul entfernen oder die Verbindung physisch trennen / trennen können, versuchen Sie dies.
Ich hatte so ein Problem. Dies war ein Programm, mit dem ich + gestartet strace
und unterbrochen hatte . Es endete in einem (verfolgten oder gestoppten) Zustand. Ich weiß nicht genau, wie es passiert ist, aber es war nicht zu töten .Ctrl
C
T
SIGKILL
Lange Rede kurzer Sinn, ich habe es geschafft, es zu töten mit gdb
:
gdb -p <PID>
> kill
Kill the program being debugged? (y or n) y
> quit
Basierend auf einem Hinweis aus der Antwort von Gilles hatte ich oben ( <defunct>
in ps) einen Prozess mit der Bezeichnung "Z" , der Systemressourcen verwendete. Es war sogar ein Port geöffnet, der LISTEN'ing war, und Sie konnten eine Verbindung zu diesem Port herstellen. Dies war nach dem Ausführen eines kill -9
darauf. Sein Elternteil war "1" (dh init
), also sollte es theoretisch gerade wiederholt werden und verschwinden. Aber es war nicht, es blieb herum, obwohl es nicht rannte und "nicht starb".
Also in meinem Fall war es Zombie, verbraucht aber immer noch Ressourcen ... FWIW.
Und es war nicht angreifbar durch eine beliebige Anzahl von kill -9
‚s
Und seine Eltern waren, init
aber es wurde nicht geerntet (aufgeräumt). Ich init
hatte ein Zombiekind.
Ein Neustart war nicht erforderlich, um das Problem zu beheben. Ein Neustart hätte das Problem "umgangen" / das Herunterfahren beschleunigt. Einfach nicht anmutig, was noch möglich war.
Und es war ein LISTEN-Port, der einem Zombie-Prozess gehört (und einige andere Ports, wie der CLOSE_WAIT-Status, verbanden localhost mit localhost). Und es akzeptierte sogar noch Verbindungen. Auch als Zombie. Ich denke, es war noch nicht gelungen, die Ports zu bereinigen, sodass eingehende Verbindungen immer noch zum Rückstand des TCP-Abhörports hinzugefügt wurden, obwohl sie keine Chance hatten, akzeptiert zu werden.
Viele der obigen Aussagen werden an verschiedenen Stellen in den Interwebs als "unmöglich" bezeichnet.
Es stellte sich heraus, dass ich einen internen Thread darin hatte, der einen "Systemaufruf" (in diesem Fall ioctl) ausführte, dessen Rückkehr einige Stunden in Anspruch nahm (dies war das erwartete Verhalten). Anscheinend kann das System den Prozess nicht "den ganzen Weg" abbrechen, bis es vom ioctl
Aufruf zurückkehrt . Nach ein paar Stunden kehrte es zurück, die Dinge klärten sich und die Steckdosen wurden wie erwartet automatisch geschlossen. Das ist einige Zeit in der Todeszelle! Der Kernel wartete geduldig darauf, ihn zu töten.
Um auf das OP zu antworten, muss man manchmal warten. Eine lange Zeit. Dann wird der Kill endlich dauern.
Überprüfen Sie auch dmesg, um festzustellen, ob eine Kernel-Panik (dh ein Kernel-Fehler) aufgetreten ist.