Šta je signal
Signal je poruka od jedne reči koju kernel isporučuje procesu: „terminal se zatvorio“, „dirnuo si nevažeću memoriju“, „molim te, stani“. Proces može da instalira handler za većinu njih, da ih ignoriše, ili da prihvati podrazumevanu akciju, koja je obično prekid (ponekad uz core dump). Dva se ne mogu ni uhvatiti ni ignorisati: SIGKILL odmah gasi proces, a SIGSTOP ga zamrzava.
TERM naspram KILL
kill PID šalje SIGTERM: zahtev. Dobro napisan program ga hvata, završava tekući zahtev, upisuje bafere u datoteke, zatvara konekcije i izlazi; to je ono što systemd, Docker i Kubernetes šalju prvo. kill -9 šalje SIGKILL: kernel uklanja proces bez izvršavanja ijednog njegovog koda, pa zaključavanja ostaju zauzeta, privremene datoteke ostaju, a upisi u toku se gube. Koristite ga tek kada je TERM dobio vreme (systemd čeka TimeoutStopSec, Docker podrazumevano 10 sekundi) i nije uspeo.
Signali kao API
- SIGHUP: demoni ponovo učitavaju konfiguraciju (nginx, sshd, HAProxy sa
-sfsemantikom kroz systemd reload). Za proces u prvom planu znači da je terminal nestao;nohupga ignoriše. - SIGUSR1 / SIGUSR2: definiše ih program. nginx ponovo otvara logove na USR1 i nadograđuje svoju binarnu datoteku na USR2;
ddispisuje napredak na USR1; Gunicorn i Unicorn ih koriste za graceful restart. - SIGPIPE: upis u pipe čiji je čitalac izašao. Njegova podrazumevana akcija, prekid, razlog je zašto se
yes | headzavršava i zašto serveri moraju da ga ignorišu ili obrađuju greške pri upisu. - SIGCHLD: dete je izašlo; roditelji pokupe decu pomoću
wait(), a roditelj koji to ne radi ostavlja zombije. - SIGWINCH: terminalu je promenjena veličina; editori i multiplekseri ponovo iscrtavaju.
Slanje signala
kill -TERM 1234 # po nazivu (ili kill -15 1234)
kill -s USR1 $(pidof nginx)
pkill -HUP sshd # po imenu procesa
killall -9 runaway # svi procesi sa tim imenom
systemctl kill -s HUP myservice
docker kill --signal=SIGUSR1 container Brojevi 1–15 su isti na svakom Unix-u; iznad toga se razlikuju po arhitekturi (SIGUSR1 je 10 na x86, a 30 na SPARC/MIPS), zbog čega skripte treba da koriste nazive.
Pitanja
Koja je razlika između SIGTERM i SIGKILL?
SIGTERM traži od procesa da izađe i može se obraditi; SIGKILL ga gasi odmah i ne može se uhvatiti. Uvek prvo probajte TERM; KILL je za procese koji su zaglavljeni.
Šta je signal 11 / SIGSEGV?
Segmentation fault: program je čitao ili pisao memoriju koja mu ne pripada, obično null ili viseći pokazivač u C/C++ kodu ili bag u nativnoj ekstenziji. Školjka prijavljuje izlazni kod 139.
Zašto je moj proces izašao sa 137 kad niko nije pokrenuo kill -9?
Kernel jeste: out-of-memory killer šalje SIGKILL najvećem procesu kada ponestane memorije, a container runtime-ovi rade isto kada se dostigne ograničenje memorije. Proverite dmesg ili OOMKilled zastavicu kontejnera.
Mogu li da ignorišem SIGINT da Ctrl-C ne zaustavlja moju skriptu?
Da: trap "" INT u bash-u, ili signal.signal(SIGINT, SIG_IGN) u Python-u. Obično je bolje uhvatiti ga i počistiti pre izlaska, tako da korisnik i dalje može da zaustavi skriptu.