Auf POSIX-Systemen haben Terminierungssignale normalerweise die folgende Reihenfolge (gemäß vielen MAN-Seiten und der POSIX-Spezifikation):
SIGTERM - Bitten Sie höflich um die Beendigung eines Prozesses. Es wird ordnungsgemäß beendet, alle Ressourcen (Dateien, Sockets, untergeordnete Prozesse usw.) bereinigt, temporäre Dateien gelöscht usw.
SIGQUIT - energischere Anfrage. Es wird unansehnlich beendet und bereinigt weiterhin Ressourcen, die unbedingt bereinigt werden müssen, löscht jedoch möglicherweise keine temporären Dateien, schreibt möglicherweise irgendwo Debug-Informationen. Auf einigen Systemen wird auch ein Core-Dump geschrieben (unabhängig davon, ob das Signal von der App abgefangen wird oder nicht).
SIGKILL - energischste Anfrage. Der Prozess wird nicht einmal aufgefordert, etwas zu tun, aber das System bereinigt den Prozess, ob es ihm gefällt oder nicht. Höchstwahrscheinlich wird ein Core Dump geschrieben.
Wie passt SIGINT in dieses Bild? Ein CLI-Prozess wird normalerweise von SIGINT beendet, wenn der Benutzer CRTL + C drückt. Ein Hintergrundprozess kann jedoch auch von SIGINT mit dem Dienstprogramm KILL beendet werden. Was ich in den Spezifikationen oder den Header-Dateien nicht sehen kann, ist, ob SIGINT mehr oder weniger stark als SIGTERM ist oder ob es überhaupt einen Unterschied zwischen SIGINT und SIGTERM gibt.
AKTUALISIEREN:
Die beste Beschreibung der Terminierungssignale, die ich bisher gefunden habe, finden Sie in der GNU LibC-Dokumentation . Es erklärt sehr gut, dass es einen beabsichtigten Unterschied zwischen SIGTERM und SIGQUIT gibt.
Es heißt über SIGTERM:
Es ist der normale Weg, ein Programm höflich um Beendigung zu bitten.
Und es heißt über SIGQUIT:
[...] und erzeugt einen Core-Dump, wenn er den Prozess beendet, genau wie ein Programmfehlersignal. Sie können sich dies als eine Programmfehlerbedingung vorstellen, die vom Benutzer „erkannt“ wurde. [...] Bestimmte Arten von Bereinigungen werden bei der Handhabung von SIGQUIT am besten weggelassen. Wenn das Programm beispielsweise temporäre Dateien erstellt, sollte es die anderen Beendigungsanforderungen durch Löschen der temporären Dateien verarbeiten. Für SIGQUIT ist es jedoch besser, sie nicht zu löschen, damit der Benutzer sie in Verbindung mit dem Core-Dump untersuchen kann.
Und SIGHUP wird auch gut genug erklärt. SIGHUP ist nicht wirklich ein Beendigungssignal, es bedeutet nur, dass die "Verbindung" zum Benutzer unterbrochen wurde, sodass die App nicht erwarten kann, dass der Benutzer weitere Ausgaben liest (z. B. stdout / stderr-Ausgabe), und dass keine Eingabe von der zu erwarten ist Benutzer nicht mehr. Für die meisten Apps bedeutet dies, dass sie besser beendet werden. Theoretisch könnte eine App auch entscheiden, dass sie beim Empfang eines SIGHUP in den Dämonmodus wechselt und nun als Hintergrundprozess ausgeführt wird und die Ausgabe in eine konfigurierte Protokolldatei schreibt. Für die meisten Daemons, die bereits im Hintergrund ausgeführt werden, bedeutet SIGHUP normalerweise, dass sie ihre Konfigurationsdateien erneut überprüfen müssen, sodass Sie sie nach dem Bearbeiten der Konfigurationsdateien an Hintergrundprozesse senden.
Es gibt jedoch keine nützliche Erklärung für SIGINT auf dieser Seite, außer dass es von CRTL + C gesendet wird. Gibt es einen Grund, warum man SIGINT anders als SIGTERM behandeln würde? Wenn ja, aus welchem Grund und wie wäre die Handhabung anders?
sudo fuser -l
an Ihrer Eingabeaufforderung finden. Für mich bringt dies:HUP INT QUIT ILL TRAP ABRT IOT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH IO PWR SYS UNUSED
kill -l
eine Liste der Signale.Antworten:
SIGTERM und SIGKILL sind für allgemeine Anforderungen zum Beenden dieses Prozesses vorgesehen. SIGTERM (standardmäßig) und SIGKILL (immer) führen zur Beendigung des Prozesses. SIGTERM kann vom Prozess erfasst werden (z. B. damit es seine eigene Bereinigung durchführen kann, wenn es möchte) oder sogar vollständig ignoriert werden. aber SIGKILL kann nicht gefangen oder ignoriert werden.
SIGINT und SIGQUIT sind speziell für Anforderungen vom Terminal vorgesehen: Zur Erzeugung dieser Signale können bestimmte Eingabezeichen zugewiesen werden (abhängig von den Einstellungen der Terminalsteuerung). Die Standardaktion für SIGINT ist dieselbe Art der Prozessbeendigung wie die Standardaktion für SIGTERM und die unveränderliche Aktion für SIGKILL. Die Standardaktion für SIGQUIT ist auch die Prozessbeendigung. Es können jedoch zusätzliche implementierungsdefinierte Aktionen auftreten, z. B. die Generierung eines Core-Dumps. Kann bei Bedarf vom Prozess abgefangen oder ignoriert werden.
SIGHUP soll, wie Sie sagen, anzeigen, dass die Terminalverbindung unterbrochen wurde, und kein Abschlusssignal als solches sein. Die Standardaktion für SIGHUP (wenn der Prozess sie nicht abfängt oder ignoriert) besteht darin, den Prozess auf die gleiche Weise wie SIGTERM usw. zu beenden.
In den POSIX- Definitionen gibt es eine Tabelle, in der
signal.h
die verschiedenen Signale sowie ihre Standardaktionen und -zwecke aufgeführt sind, und das Kapitel Allgemeine Terminalschnittstelle enthält ausführlichere Informationen zu den terminalbezogenen Signalen.quelle
Wie DarkDust feststellte, haben viele Signale die gleichen Ergebnisse, aber Prozesse können ihnen unterschiedliche Aktionen zuordnen, indem sie unterscheiden, wie jedes Signal erzeugt wird. Wenn ich mir den FreeBSD-Kernel-Quellcode (kern_sig.c) ansehe, sehe ich, dass die beiden Signale auf die gleiche Weise behandelt werden, den Prozess beenden und an einen beliebigen Thread geliefert werden.
quelle
man 7 signal
Dies ist die praktische nicht normative Manpage des Linux-Manpages-Projekts , in der Sie häufig nach Linux-Signalinformationen suchen möchten.
Version 3.22 erwähnt interessante Dinge wie:
und enthält die Tabelle:
Action
Dies fasst das Signal zusammen , das zB SIGQUIT von SIGQUIT unterscheidet, da SIGQUIT AktionCore
und SIGINT hatTerm
.Die Aktionen sind im selben Dokument dokumentiert:
Ich kann aus Sicht des Kernels keinen Unterschied zwischen SIGTERM und SIGINT erkennen, da beide Aktionen haben
Term
und beide abgefangen werden können. Es scheint, dass dies nur eine "Unterscheidung zwischen allgemeinen Verwendungskonventionen" ist:kill
Einige Signale sind ANSI C und andere nicht
Ein wesentlicher Unterschied ist, dass:
Sie sind in Abschnitt "7.14 Signalbehandlung" des C99-Entwurfs N1256 beschrieben :
Das macht SIGINT zu einem guten Kandidaten für eine interaktive Strg + C.
POSIX 7
POSIX 7 dokumentiert die Signale mit dem
signal.h
Header: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.htmlDiese Seite enthält auch die folgende Tabelle von Interesse, in der einige der Dinge erwähnt werden, die wir bereits gesehen haben
man 7 signal
:BusyBox init
Die Standardeinstellung 1.29.2 von BusyBox
reboot
sendet ein SIGTERM an Prozesse, schläft für eine Sekunde und sendet dann SIGKILL. Dies scheint eine gemeinsame Konvention für verschiedene Distributionen zu sein.Wenn Sie ein BusyBox-System herunterfahren mit:
Es sendet ein Signal an den Init-Prozess.
Dann ruft der Init-Signal-Handler auf:
welches auf dem Terminal druckt:
Hier ist ein minimales konkretes Beispiel dafür .
Vom Kernel gesendete Signale
quelle
Nach einer schnellen Google-Suche nach sigint vs sigterm scheint der einzige beabsichtigte Unterschied zwischen den beiden darin zu bestehen, ob es durch eine Tastenkombination oder durch einen expliziten Aufruf von initiiert wurde
kill
.Infolgedessen können Sie beispielsweise Sigint abfangen und etwas Besonderes damit tun, da Sie wissen, dass es wahrscheinlich über eine Tastenkombination gesendet wurde. Aktualisieren Sie möglicherweise den Bildschirm oder etwas anderes, anstatt zu sterben (nicht empfohlen, da die Leute erwarten
^C
, das Programm zu beenden, nur ein Beispiel).Ich habe auch gelernt, dass
^\
Sigquit gesendet werden sollte, das ich selbst verwenden kann. Sieht sehr nützlich aus.quelle
Mit
kill
(sowohl dem Systemaufruf als auch dem Dienstprogramm) können Sie fast jedes Signal an jeden Prozess senden, sofern Sie über die Berechtigung verfügen. Ein Prozess kann nicht unterscheiden, wie ein Signal zum Leben erweckt wurde und wer es gesendet hat.Davon abgesehen soll SIGINT wirklich die Strg-C-Unterbrechung singalisieren, während SIGTERM das allgemeine Terminalsignal ist. Es gibt kein Konzept dafür, dass ein Signal "stärker" ist, mit der einzigen Ausnahme, dass es Signale gibt, die nicht blockiert oder verarbeitet werden können (SIGKILL und SIGSTOP laut Manpage).
Ein Signal kann nur "stärker" sein als ein anderes Signal, wenn es darum geht, wie ein Empfangsprozess mit dem Signal umgeht (und wie die Standardaktion für dieses Signal lautet). Beispielsweise führen sowohl SIGTERM als auch SIGINT standardmäßig zur Beendigung. Wenn Sie SIGTERM jedoch ignorieren, wird Ihr Prozess nicht beendet, während SIGINT dies weiterhin tut.
quelle
Mit Ausnahme einiger weniger Signale können Signalhandler die verschiedenen Signale abfangen oder das Standardverhalten beim Empfang eines Signals kann geändert werden. Weitere
signal(7)
Informationen finden Sie in der Manpage.quelle
SIGINT
Signal (" Programmunterbrechung ") wird gesendet, wenn der Benutzer das INTR-Zeichen (normalerweiseC-c
) eingibt ." "SIGINT 2 Term Interrupt von der Tastatur" Sie drücken Strg-C,SIGINT
wird gesendet. Der Prozess stirbt normalerweise ab. Was gibt es noch zu geben?