Signallar — kill, SIGTERM va SIGKILL

~10 daq · Linux · Jarayonlar va tizim

Muammodan boshlaylik

top da ko'rdingiz: node jarayoni 100% CPU va javob bermayapti. Uni to'xtatish kerak. Internetda maslahat: kill -9 2214. Ishladi. Lekin ertasi kuni bazada yarim saqlangan buyurtmalar, buzilgan fayllar...

kill -9 — "elektr vilkasini sug'urib olish". Ba'zan kerak, lekin birinchi tanlov emas. Jarayonni to'g'ri to'xtatish uchun signallar qanday ishlashini bilish kerak.


Signal nima?

Signal — operatsion tizim jarayonga yuboradigan qisqa xabar: "to'xta", "qayta yukla", "uxla". Jarayon ko'pchilik signallarni ushlab, o'zicha javob bera oladi.

Signal Raqam Ma'nosi Ushlash mumkinmi
SIGTERM 15 "Iltimos, to'xta" — standart ✅
SIGINT 2 Ctrl+C — "to'xtat" ✅
SIGKILL 9 Darhol o'ldirish — yadro tomonidan ❌
SIGHUP 1 Terminal yopildi / "sozlamalarni qayta o'qi" ✅
SIGSTOP 19 Muzlatish (pauza) ❌
SIGCONT 18 Davom etish ✅
SIGTSTP 20 Ctrl+Z — pauza ✅
kill -l            # barcha signallar ro'yxati

SIGTERM va SIGKILL — asosiy farq

SIGTERM — muloyim so'rov. Jarayon uni ushlaydi va to'g'ri yopiladi:

  • Joriy so'rovlarni tugatadi
  • Bazaga ulanishlarni yopadi
  • Buferdagi ma'lumotlarni diskka yozadi
  • Vaqtinchalik fayllarni tozalaydi
  • Keyin chiqadi

SIGKILL — jarayonga umuman yetib bormaydi: yadro uni darhol o'chiradi. Hech qanday tozalash yo'q:

  • Yarim yozilgan fayllar buzilishi mumkin
  • Tranzaksiyalar uzilib qoladi
  • Lock-fayllar qoladi ("another instance is running")
SIGTERM:  "Ish kuni tugadi, narsalaringizni yig'ib, uyga boring"
SIGKILL:  Qo'riqchi xodimni stoldan ko'tarib, eshikdan chiqarib yuboradi

kill — signal yuborish

Nomi chalg'itadi: kill — "o'ldirish" emas, signal yuborish:

kill 2214              # SIGTERM (standart)
kill -15 2214          # xuddi shu
kill -TERM 2214        # xuddi shu
kill -9 2214           # SIGKILL
kill -HUP 1104         # SIGHUP

To'g'ri tartib

kill 2214              # 1. Muloyim so'rash
sleep 5
ps -p 2214             # 2. Hali tirikmi?
kill -9 2214           # 3. Faqat javob bermasa — majburan

[!WARNING] kill -9 — oxirgi chora. Avval doimo oddiy kill (SIGTERM) bilan urinib ko'ring va bir necha soniya kuting. Ayniqsa bazalar (MySQL, PostgreSQL) uchun SIGKILL ma'lumotlar buzilishiga olib kelishi mumkin.

Nom bo'yicha

pkill node                  # barcha node jarayonlariga SIGTERM
pkill -f "server.js"        # to'liq buyruqda "server.js" bo'lganlarga
pkill -u malika             # malikaning barcha jarayonlariga
killall nginx               # nomi aynan "nginx" bo'lganlarga

[!WARNING] pkill naqsh bo'yicha ishlaydi: pkill node — "node" so'zi bor barcha jarayonlarni topadi. Avval pgrep -a node bilan ro'yxatni tekshiring.

Boshqa foydalanuvchining jarayoniga signal yuborish uchun — sudo.


SIGHUP — sozlamalarni qayta yuklash

Ko'p xizmatlar SIGHUP ni "sozlamalarni qayta o'qi" deb tushunadi — to'xtamasdan:

sudo kill -HUP $(pidof -s nginx)      # yoki:
sudo nginx -s reload
sudo systemctl reload nginx           # eng to'g'ri usul (25-dars)

Nginx yangi sozlamani o'qiydi, mavjud ulanishlar uzilmaydi — foydalanuvchilar hech narsani sezmaydi.


Ilovada signallarni ushlash

O'z ilovangiz SIGTERM ga to'g'ri javob berishi kerak. Node.js:

const server = app.listen(3000);

process.on('SIGTERM', () => {
  console.log('SIGTERM olindi, yopilmoqda...');
  server.close(() => {          // yangi so'rovlarni qabul qilmaslik, joriylarni tugatish
    db.end();                   // bazani yopish
    process.exit(0);
  });
});

Python:

import signal, sys

def toxta(sig, frame):
    print("Yopilmoqda...")
    sys.exit(0)

signal.signal(signal.SIGTERM, toxta)

systemctl stop (25-dars) va docker stop aynan shunday ishlaydi: avval SIGTERM, kutish (systemd — 90 soniya, Docker — 10 soniya), keyin SIGKILL. Ilova SIGTERM ni e'tiborsiz qoldirsa — har bir to'xtatish shuncha kutish va oxirida "qo'pol" o'ldirish.


Muzlatish va davom ettirish

kill -STOP 2214        # muzlatish — CPU ishlatmaydi, lekin xotirada qoladi
kill -CONT 2214        # davom ettirish

Og'ir jarayonni vaqtincha to'xtatib, serverga "nafas olish" imkonini berish uchun.


Zombi jarayonlar

ps aux da Z holatli yoki <defunct> jarayonlar:

otabek  3301  0.0  0.0  0  0 ?  Z  10:15  0:00 [node] <defunct>

Zombi — tugagan, lekin otasi hali uning natijasini "qabul qilmagan" jarayon. Resurs ishlatmaydi (faqat jarayonlar jadvalida joy). Uni kill qilib bo'lmaydi — u allaqachon o'lgan. Yechim — ota jarayonni qayta ishga tushirish. Bir nechtasi — muammo emas; minglab to'planayotgan bo'lsa — ota dasturda xato bor.


Nima uchun shunday?

Nima uchun SIGKILL ni ushlab bo'lmaydi?

Chunki tizimga kafolatlangan to'xtatish usuli kerak. Agar har qanday signalni ushlash mumkin bo'lsa, xato yoki zararli dastur barcha signallarni e'tiborsiz qoldirib, abadiy ishlashi mumkin edi — administrator uni to'xtata olmasdi. SIGKILL (va SIGSTOP) jarayonga yetkazilmaydi: yadro uni to'g'ridan-to'g'ri o'chiradi. Bu — tizimning so'nggi xavfsizlik klapani. Lekin aynan shu kafolat uni "qo'pol" qiladi: jarayonga hech qanday imkon berilmaydi. Shuning uchun tartib: avval so'rash (SIGTERM), keyin majburlash (SIGKILL).


Xulosa

Eslab qoling:

  • Signal — jarayonga xabar; kill — signal yuborish
  • SIGTERM (15) — muloyim, standart; jarayon to'g'ri yopiladi
  • SIGKILL (9) — darhol, ushlab bo'lmaydi; oxirgi chora
  • SIGINT — Ctrl+C; SIGHUP — ko'pincha "sozlamalarni qayta o'qi"
  • Tartib: kill PID → kutish → kill -9 PID
  • pkill -f naqsh, killall nom — avval pgrep -a bilan tekshiring
  • Ilovangizda SIGTERM ni ushlang — systemctl stop va docker stop uchun
  • Zombi — otani qayta ishga tushiring

Keyingi dars

24-dars: Fon jarayonlar — &, jobs, nohup, tmux