Es verwirrt mich oft, dass ich, obwohl ich seit mehreren Jahrzehnten professionell mit Computern und Linux arbeite, den größten Teil der Betriebssystemfunktionen wie eine Black Box behandle, nicht anders als Magie.
Heute habe ich über den kill
Befehl nachgedacht , und während ich ihn mehrmals am Tag verwende (sowohl in seiner "normalen" als auch in seiner typischen -9
Form), muss ich zugeben, dass ich absolut keine Ahnung habe, wie er hinter den Kulissen funktioniert.
Wenn ein laufender Prozess aus meiner Sicht "hängt", rufe ich kill
seine PID auf und dann läuft er plötzlich nicht mehr. Magie!
Was passiert dort wirklich? Manpages sprechen von "Signalen", aber das ist sicherlich nur eine Abstraktion. Das Senden kill -9
an einen Prozess erfordert nicht die Kooperation des Prozesses (wie das Behandeln eines Signals), sondern beendet ihn nur.
- Wie verhindert Linux, dass der Prozess weiterhin CPU-Zeit in Anspruch nimmt?
- Wird es aus der Planung entfernt?
- Trennt es den Prozess von seinen geöffneten Dateihandles?
- Wie wird der virtuelle Speicher des Prozesses freigegeben?
- Gibt es so etwas wie eine globale Tabelle im Speicher, in der Linux Verweise auf alle von einem Prozess beanspruchten Ressourcen speichert, und wenn ich einen Prozess "abbringe", geht Linux diese Tabelle einfach durch und gibt die Ressourcen nacheinander frei?
Ich würde das wirklich gerne alles wissen!
quelle
kill -9
Verweis .Antworten:
Sie nehmen an, dass einige Signale, da sie abgefangen und ignoriert werden können, alle eine Kooperation beinhalten. Aber wie pro
man 2 signal
„ die Signale SIGKILL und SIGSTOP nicht gefangen oder ignoriert werden“. SIGTERM kann abgefangen werden, weshalb Plainkill
nicht immer effektiv ist - im Allgemeinen bedeutet dies, dass etwas im Handler des Prozesses schief gelaufen ist. 1Wenn ein Prozess keinen Handler für ein bestimmtes Signal definiert (oder nicht definieren kann), führt der Kernel eine Standardaktion aus. Im Falle von SIGTERM und SIGKILL, das den Prozess zu beenden ist (es sei denn , seine PID 1 ist, wird der Kernel nicht beendet
init
) 2 werden ihre Datei - Handles Bedeutung geschlossen, dessen Speicher an das System Pool zurückgegeben, seine Eltern erhält SIGCHILD, seine Waise Kinder werden von init usw. geerbt, so als ob es aufgerufen hätteexit
(sieheman 2 exit
). Der Prozess existiert nicht mehr - es sei denn, er endet als Zombie. In diesem Fall wird er in der Prozesstabelle des Kernels mit einigen Informationen aufgeführt. Das passiert, wenn sein Elternteil es nicht tutwait
und mit diesen Informationen richtig umgehen. Zombie-Prozessen ist jedoch kein Speicher mehr zugeordnet und sie können daher nicht weiter ausgeführt werden.Ich denke das ist genau genug. Der physische Speicher wird seitenweise nachverfolgt (eine Seite entspricht normalerweise einem 4-KB-Block), und diese Seiten werden aus einem globalen Pool entnommen und an diesen zurückgegeben. Etwas komplizierter ist es, dass einige freigegebene Seiten zwischengespeichert werden, falls die darin enthaltenen Daten erneut benötigt werden (dh Daten, die aus einer noch vorhandenen Datei gelesen wurden).
Klar, alle Signale sind eine Abstraktion. Sie sind konzeptionell, genau wie "Prozesse". Ich spiele ein bisschen Semantik, aber wenn Sie meinen, SIGKILL ist qualitativ anders als SIGTERM, dann ja und nein. Ja in dem Sinne, dass es nicht aufgefangen werden kann, aber nein in dem Sinne, dass beide Signale sind. Analog dazu ist ein Apfel keine Orange, aber Äpfel und Orangen sind nach einer vorgefassten Definition beide Früchte. SIGKILL scheint mehr abstrakt , da Sie es nicht fangen können, aber es ist immer noch ein Signal. Hier ist ein Beispiel für die Handhabung von SIGTERM. Ich bin sicher, dass Sie diese bereits gesehen haben:
Dieser Prozess wird nur für immer schlafen. Sie können es in einem Terminal ausführen und mit SIGTERM senden
kill
. Es spuckt Sachen aus wie:1066 ist meine UID. Die PID ist die der Shell, von der aus
kill
ausgeführt wird, oder die PID von kill, wenn Sie sie aufteilen (kill 25309 & echo $?
).Auch hier macht es keinen Sinn, einen Handler für SIGKILL festzulegen, da dies nicht funktioniert. 3 Wenn ich
kill -9 25309
den Prozess beenden wird. Aber das ist immer noch ein Signal. Der Kernel hat die Information, wer das Signal gesendet hat , welche Art von Signal es ist, etc.1. Wenn Sie sich die Liste der möglichen Signale nicht angesehen haben , lesen Sie
kill -l
.2. Eine weitere Ausnahme, wie Tim Post weiter unten erwähnt, gilt für Prozesse im unterbrechungsfreien Schlaf . Diese können erst aufgeweckt werden, wenn das zugrunde liegende Problem behoben ist. Daher werden ALLE Signale (einschließlich SIGKILL) für die Dauer zurückgestellt. Ein Prozess kann diese Situation jedoch nicht absichtlich erzeugen.
3. Dies bedeutet nicht, dass die Verwendung
kill -9
in der Praxis besser ist. Mein Beispiel-Handler ist in dem Sinne schlecht, dass er nicht dazu führtexit()
. Der eigentliche Zweck eines SIGTERM-Handlers besteht darin, dem Prozess die Möglichkeit zu geben, z. B. temporäre Dateien zu bereinigen und diese dann freiwillig zu beenden. Wenn Sie verwendenkill -9
, hat dies keine Chance. Tun Sie dies nur, wenn der Teil "freiwillig beenden" fehlgeschlagen zu sein scheint.quelle
-9
womit töten Sie den Prozess, denn das ist das eigentliche Problem, wer will, dass dieser stirbt? ;)kill -9
funktioniert der Versuch, bestimmte I / O-gebundene Prozesse zu erreichen, nicht, zumindest nicht sofort.kill -9
nicht abgefangen werden kann, kann ein Prozess, der es empfängt, keine Bereinigung durchführen (z. B. temporäre Dateien entfernen, gemeinsam genutzten Speicher freigeben usw.), bevor er beendet wird. Verwenden Sie daherkill -9
(akakill -kill
) nur als letzten Ausweg. Beginnen Sie mit einemkill -hup
und / oderkill -term
zuerst und verwenden Sie dannkill -kill
als letzten Schlag.Jeder Prozess wird für eine geplante Zeit ausgeführt und dann vom Hardware-Timer unterbrochen, um den CPU-Kern für andere Aufgaben bereitzustellen. Dies ist der Grund, warum es möglich ist, viel mehr Prozesse als CPU-Kerne zu haben oder sogar alle Betriebssysteme mit vielen Prozessen auf einer einzigen Kern-CPU auszuführen.
Nachdem der Prozess unterbrochen wurde, kehrt die Steuerung zum Kernel-Code zurück. Dieser Code kann dann entscheiden, die Ausführung des unterbrochenen Prozesses nicht fortzusetzen, ohne dass die Prozessseite mitarbeitet. kill -9 kann in jeder Zeile Ihres Programms ausgeführt werden.
quelle
Hier ist eine idealisierte Beschreibung, wie das Beenden eines Prozesses funktioniert. In der Praxis wird jede Unix-Variante viele zusätzliche Komplikationen und Optimierungen aufweisen.
Der Kernel verfügt über eine Datenstruktur für jeden Prozess, in der Informationen darüber gespeichert sind, welchen Speicher er zuordnet, welche Threads er hat und wann sie geplant sind, welche Dateien er geöffnet hat usw. Wenn der Kernel einen Prozess abbricht, macht er eine Notiz in Die Datenstruktur des Prozesses (und möglicherweise in der Datenstruktur jedes Threads), die der Prozess beenden soll.
Wenn einer der Prozessthreads derzeit auf einer anderen CPU geplant ist, löst der Kernel möglicherweise einen Interrupt auf dieser anderen CPU aus, damit dieser Thread nicht mehr schneller ausgeführt wird.
Wenn der Scheduler feststellt, dass sich ein Thread in einem Prozess befindet, der beendet werden muss, wird er nicht mehr geplant.
Wenn keiner der Prozessthreads mehr geplant ist, gibt der Kernel die Ressourcen des Prozesses frei (Speicher, Dateideskriptoren usw.). Jedes Mal, wenn der Kernel eine Ressource freigibt, prüft er, ob sein Besitzer noch über aktive Ressourcen verfügt. Sobald der Prozess keine Live-Ressource mehr hat (Speicherzuordnung, offener Dateideskriptor, ...), kann die Datenstruktur für den Prozess selbst freigegeben und der entsprechende Eintrag aus der Prozesstabelle entfernt werden.
Einige Ressourcen können sofort freigegeben werden (z. B. Freigabe von Speicher, der nicht von einer E / A-Operation verwendet wird). Andere Ressourcen müssen warten, z. B. können Daten, die eine E / A-Operation beschreiben, nicht freigegeben werden, während die E / A-Operation ausgeführt wird (während eine DMA ausgeführt wird , wird der Speicher verwendet, auf den zugegriffen wird, und das Abbrechen der DMA erfordert Kontakt mit dem Peripheriegerät). Der Fahrer für eine solche Ressource wird benachrichtigt und kann versuchen, die Stornierung zu beschleunigen. Sobald der Vorgang nicht mehr ausgeführt wird, schließt der Treiber die Freigabe dieser Ressource ab.
(Der Eintrag in der Prozesstabelle ist tatsächlich eine Ressource, die zum übergeordneten Prozess gehört und freigegeben wird, wenn der Prozess stirbt und der übergeordnete Prozess das Ereignis bestätigt .)
quelle