Mitt serverprogram fick ett SIGTERM och stoppade (med utgångskod 0). Jag är förvånad över detta, eftersom jag är ganska säker på att det fanns gott om minne för det. Under vilka förhållanden skickar Linux (upptagen låda) ett SIGTERM till en process?
Kommentarer
Svar
Jag lägger upp detta som ett svar så att det finns någon form av upplösning om detta visar sig vara problemet.
En utgångsstatus på 0 betyder en normal utgång från ett framgångsrikt program. Ett avslutande program kan välja vilket heltal som helst mellan 0 och 255 som utgångsstatus. Konventionellt använder program små värden. Värden 126 och högre används av skalet för att rapportera speciella förhållanden, så det är bäst att undvika dem.
På C API-nivå rapporterar programmen en 16-bitars status¹ som kodar både programmets utgångsstatus och signalen som dödade den, om någon.
I skalet, en kommando ”s utgångsstatus (sparad i $?
) sammanfogar programmets faktiska utgångsstatus och signalvärdet: om ett program dödas av en signal, $?
är inställt på ett värde större än 128 (för de flesta skalen är detta värde 128 plus signalnumret; ATT ksh använder 256 + signalnummer och yash använder 384 + signalnummer, vilket undviker tvetydigheten, men de andra skalen har inte följt).
I synnerhet, om $?
är 0, avslutades ditt program normalt.
Observera att detta inkluderar fallet med en process som tar emot SIGTERM men har en signalhanterare för den och slutligen slutar normalt (kanske som en indirekt konsekvens av SIGTERM-signalen, kanske inte).
För att svara på frågan i din titel skickas SIGTERM aldrig automatiskt av systemet. Det finns några signaler som skickas automatiskt som SIGHUP när en terminal går bort, SIGSEGV / SIGBUS / SIGILL när en process gör saker den inte borde göra, SIGPIPE när den skriver till ett trasigt rör / uttag, etc. Och det finns några signaler som skickas på grund av en tangenttryckning i en terminal, främst SIGINT för Ctrl + C , SIGQUIT för Ctrl + \ och SIGTSTP för Ctrl + Z , men SIGTERM är inte en av dessa. Om en process tar emot SIGTERM skickade någon annan process den signalen.
¹ grovt sagt
Kommentarer
- Trevlig förklaring av hur utgångsstatus bestäms vid mottagning av en signal. Men detta svar ' t adress OP ' s fråga.
- @codeforester Jag svarade på frågan i kropp, inte frågan i titeln. Tja, en av frågorna i kroppen – med tanke på att den var baserad på ett missförstånd är det lite rörigt. Jag ' Lägg till några ord om resten.
- Det beror på skalet. I ksh93 är det ' s 256 + signum, i yash, det ' s 384 + signum
- Observera att att använda ett värde över 256 a la ksh är inte nödvändigtvis bättre eftersom det förhindrar att det skickas till
exit
.yash
-metoden är en bra kompromiss, men se rc för en annan. Se även Standardutgångskod när processen avslutas?
Svar
SIGTERM är signalen som vanligtvis används för att administrativt avsluta en process.
Det är inte en signal som kärnan skulle skicka, men det är signalen som en process vanligtvis skulle skicka för att avsluta (graciöst) en annan process.
Det är signalen som sänds som standard av kill
, pkill
, killall
… kommandon.
Det är signalen som skickas till demoner för att stoppa dem (som på en service some-service stop
), eller skickas av init
före avstängning (följt av SIGKILL för de processer som inte har lyckats avslutas i tid vid SIGTERM).
Observera att SIGTERM är inte signalen som skickas vid ^C
. Signalen som skickas till ^C
är SIGINT.
$?
ställas in på 143 (128 + signalnummer).