Das Senden von kill -9 an einen Prozess erfordert nicht die Kooperation des Prozesses (wie das Behandeln eines Signals), sondern beendet ihn nur.
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 Plain kill
nicht immer effektiv ist - im Allgemeinen bedeutet dies, dass etwas im Handler des Prozesses schief gelaufen ist. 1
Wenn 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ätte exit
(siehe man 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.
Gibt es so etwas wie eine globale Tabelle im Speicher, in der Linux Verweise auf alle von einem Prozess belegten Ressourcen speichert, und wenn ich einen Prozess "abbringe", geht Linux diese Tabelle einfach durch und gibt die Ressourcen nacheinander frei?
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).
Manpages sprechen von "Signalen", aber das ist sicherlich nur eine Abstraktion.
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:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
void sighandler (int signum, siginfo_t *info, void *context) {
fprintf (
stderr,
"Received %d from pid %u, uid %u.\n",
info->si_signo,
info->si_pid,
info->si_uid
);
}
int main (void) {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = sighandler;
sa.sa_flags = SA_SIGINFO;
sigaction(SIGTERM, &sa, NULL);
while (1) sleep(10);
return 0;
}
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:
Received 15 from pid 25331, uid 1066.
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ührt exit()
. 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 verwenden kill -9
, hat dies keine Chance. Tun Sie dies nur, wenn der Teil "freiwillig beenden" fehlgeschlagen zu sein scheint.
kill -9
Verweis .