Ich bin manchmal ein wenig verwirrt von all den Signalen, die ein Prozess empfangen kann. Soweit ich weiß, hat ein Prozess für jedes dieser Signale einen Standard-Handler ( Signaldisposition ), kann jedoch durch Aufrufen einen eigenen Handler bereitstellen sigaction()
.
Hier ist also meine Frage: Wodurch werden die einzelnen Signale gesendet? Ich weiß, dass Sie über den -s
Parameter to manuell Signale an laufende Prozesse senden können. Unter kill
welchen natürlichen Umständen werden diese Signale gesendet? Wann wird zum Beispiel SIGINT
gesendet?
Gibt es auch Einschränkungen, mit welchen Signalen umgegangen werden kann? Können sogar SIGSEGV
Signale verarbeitet und die Steuerung an die Anwendung zurückgegeben werden?
Antworten:
Zusätzlich zu den aufrufenden Prozessen
kill(2)
werden einige Signale vom Kernel (oder manchmal vom Prozess selbst) unter verschiedenen Umständen gesendet:SIGINT
(bitte kehren Sie zur Hauptschleife zurück) am Ctrl+ C,SIGQUIT
(bitte sofort beenden) am Ctrl+ \,SIGTSTP
(bitte aussetzen) am Ctrl+ Z. Die Schlüssel können mit demstty
Befehl geändert werden .SIGTTIN
undSIGTTOU
werden gesendet, wenn ein Hintergrundprozess versucht, auf sein steuerndes Terminal zu lesen oder zu schreiben.SIGWINCH
wird gesendet, um anzuzeigen, dass sich die Größe des Terminalfensters geändert hat.SIGHUP
gesendet wird , um das Signal , dass das Terminal verschwunden ist ( in der Vergangenheit , weil Ihr Modem hatte h UNG bis heutzutage in der Regel , weil Sie den Terminal - Emulator - Fenster haben geschlossen).SIGBUS
für einen nicht ausgerichteten Zugriffsspeicher;SIGSEGV
für einen Zugriff auf eine nicht zugeordnete Seite;SIGILL
für eine illegale Anweisung (falscher Opcode);SIGFPE
für einen Gleitkomma-Befehl mit schlechten Argumenten (zBsqrt(-1)
).SIGALRM
benachrichtigt, dass ein vom Prozess festgelegter Timer abgelaufen ist. Timer kann Satz mit seinalarm
,setitimer
und andere.SIGCHLD
benachrichtigt einen Prozess, dass eines seiner Kinder gestorben ist.SIGPIPE
wird generiert, wenn ein Prozess versucht, in eine Pipe zu schreiben, wenn das Leseende geschlossen wurde (die Idee ist, dass, wenn Sie ausgeführtfoo | bar
und beendet werdenbar
,foo
von a getötet wirdSIGPIPE
).SIGPOLL
(auch genanntSIGIO
) benachrichtigt den Prozess, dass ein abrufbares Ereignis aufgetreten ist. POSIX gibt abfragbare Ereignisse an, die über das Symbol registriert werdenI_SETSIG
ioctl
. Viele Systeme erlauben abrufbare Ereignisse für jeden Dateideskriptor, der über dasO_ASYNC
fcntl
Flag gesetzt wird. Ein entsprechendes Signal istSIGURG
, das über dringende Daten auf einem Gerät (registriert über dieI_SETSIG
ioctl
) oder Socket informiert .SIGPWR
an alle Prozesse gesendet, wenn die USV einen bevorstehenden Stromausfall meldet.Diese Listen erheben keinen Anspruch auf Vollständigkeit. Standardsignale sind in definiert
signal.h
.Die meisten Signale können von der Anwendung erfasst und verarbeitet (oder ignoriert) werden. Die einzigen zwei tragbaren Signale, die nicht abgefangen werden können, sind
SIGKILL
(nur sterben) undSTOP
(Ausführung stoppen).SIGSEGV
( Segmentierungsfehler ) und sein CousinSIGBUS
( Busfehler ) können abgefangen werden, aber es ist eine schlechte Idee, wenn Sie nicht genau wissen, was Sie tun. Eine übliche Anwendung zum Abfangen ist das Drucken eines Stack-Trace oder anderer Debug-Informationen. Eine fortgeschrittenere Anwendung ist das Implementieren einer Art von In-Process-Speicherverwaltung oder das Abfangen falscher Anweisungen in VM-Engines.Lassen Sie mich abschließend etwas erwähnen, das kein Signal ist. Wenn Sie in einem Programm, das Eingaben vom Terminal liest, am Anfang einer Zeile Ctrl+ drücken D, wird dem Programm mitgeteilt, dass das Ende der Eingabedatei erreicht ist. Dies ist kein Signal: Es wird über die Ein- / Ausgabe-API übertragen. Wie bei Ctrl+ Cund Freunden kann die Taste mit konfiguriert werden
stty
.quelle
SIGFPE
Etwas unintuitiv wird dies auch beim ganzzahligen Teilen durch Null und manchmal beim vorzeichenbehafteten Ganzzahlüberlauf signalisiert .Um Ihre zweite Frage zuerst zu beantworten:
SIGSTOP
undSIGKILL
kann von der Anwendung nicht abgefangen werden, aber jedes andere Signal kann es sogarSIGSEGV
. Diese Eigenschaft ist für das Debuggen nützlich. Mit der richtigen Bibliotheksunterstützung können Sie beispielsweiseSIGSEGV
einen Stack-Backtrace abhören und generieren, um zu zeigen, wo genau dieser Fehler aufgetreten ist.Das offizielle Wort (jedenfalls für Linux) zu den Funktionen der einzelnen Signale können Sie über
man 7 signal
eine Linux-Befehlszeile eingeben . http://linux.die.net/man/7/signal enthält dieselben Informationen, die Tabellen sind jedoch schwerer zu lesen.Ohne Erfahrung mit Signalen ist es jedoch schwierig, anhand der kurzen Beschreibungen zu erkennen, was sie in der Praxis bewirken. Deshalb hier meine Interpretation:
Ausgelöst von der Tastatur
SIGINT
passiert, wenn du schlägstCTRL+C
.SIGQUIT
wird durch ausgelöstCTRL+\
und entleert den Kern.SIGTSTP
Unterbricht Ihr Programm, wenn Sie drückenCTRL+Z
. Im GegensatzSIGSTOP
dazu ist es catchable, was Programmen dievi
Möglichkeit gibt, das Terminal in einen sicheren Zustand zurückzusetzen, bevor sie sich selbst aussetzen.Terminal Interaktionen
SIGHUP
("Auflegen") ist das, was passiert, wenn Sie Ihr xterm schließen (oder auf andere Weise die Verbindung zum Terminal trennen), während Ihr Programm ausgeführt wird.SIGTTIN
und halten SieSIGTTOU
Ihr Programm an, wenn es versucht, vom Terminal zu lesen oder darauf zu schreiben, während es im Hintergrund ausgeführt wird. Um dasSIGTTOU
zu erreichen, muss das Programm schreiben/dev/tty
, nicht nur die Standard-Standardausgabe.Ausgelöst durch eine CPU-Ausnahme
Dies bedeutet, dass Ihr Programm versucht hat, etwas falsch zu machen.
SIGILL
bedeutet eine illegale oder unbekannte Prozessoranweisung. Dies kann beispielsweise der Fall sein, wenn Sie versuchen, direkt auf Prozessor-E / A-Ports zuzugreifen.SIGFPE
Bedeutet, dass ein Hardware-Rechenfehler aufgetreten ist. höchstwahrscheinlich hat das Programm versucht, durch Null zu teilen.SIGSEGV
bedeutet, dass Ihr Programm versucht hat, auf einen nicht zugeordneten Speicherbereich zuzugreifen.SIGBUS
bedeutet, dass das Programm auf andere Weise falsch auf den Speicher zugegriffen hat; Ich werde nicht auf Details für diese Zusammenfassung eingehen.Prozessinteraktion
SIGPIPE
passiert, wenn Sie versuchen, in eine Pipe zu schreiben, nachdem der Pipe-Reader sein Ende geschlossen hat. Sehenman 7 pipe
.SIGCHLD
tritt auf, wenn ein von Ihnen erstellter untergeordneter Prozess beendet oder angehalten wird (vonSIGSTOP
oder ähnlich).Nützlich für die Selbstsignalisierung
SIGABRT
wird normalerweise durch das Programm verursacht, das dieabort()
Funktion aufruft , und verursacht standardmäßig einen Core-Dump. Eine Art "Panikknopf".SIGALRM
wird durch denalarm()
Systemaufruf verursacht, der den Kernel veranlasst,SIGALRM
nach einer festgelegten Anzahl von Sekunden ein an das Programm zu senden. Sieheman 2 alarm
undman 2 sleep
.SIGUSR1
undSIGUSR2
verwendet werden aber das programm gefällt. Sie könnten für die Signalisierung zwischen Prozessen nützlich sein.Vom Administrator gesendet
Diese Signale werden normalerweise von der Eingabeaufforderung, über den
kill
Befehlfg
oderbg
im Fall von gesendetSIGCONT
.SIGKILL
undSIGSTOP
sind die nicht blockierbaren Signale. Der erste bricht den Vorgang immer sofort ab; der zweite unterbricht den Vorgang.SIGCONT
setzt einen angehaltenen Prozess fort.SIGTERM
ist eine auffangbare Version vonSIGKILL
.quelle
shutdown
Befehl verwendet wird?SIGTERM
wird zuerst gesendet, gefolgt von einer Verzögerung, gefolgt vonSIGKILL
. Im Prinzip muss der Kernel für ein hartes, sofortiges Herunterfahren überhaupt kein Signal senden. Es könnte einfach aufhören, den Prozess auszuführen.