10-bo‘lim

Jarayonlar va signallar

ps, pgrep, signallar va osilib qolgan dasturni to'g'ri - ma'lumot yo'qotmasdan - to'xtatish.

🕑 20 daqiqa o‘qish 📄 1 459 so‘z 👁 1 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Jarayonni ko'rish
  2. ps ning ikki uslubi
  3. pgrep va pkill - nom bo'yicha
  4. Signallar
  5. Signal ushlanadimi - tajriba
  6. Bir necha jarayon: ota va bola
  7. Zombi va yetim
  8. Ustuvorlik: nice va renice
  9. Fon rejimida ishga tushirish
  10. Jarayon nima qilayotganini bilish
  11. Xulosa

Har ishlayotgan dastur - jarayon. Uning raqami (PID), ota-onasi, egasi, holati va o'z xotirasi bor. Serverda nimadir noto'g'ri ketganda, javob deyarli har doim jarayonlar ro'yxatida yotadi.

Jarayonni ko'rish #

Terminal
cat > xizmat.sh <<'EOF'
#!/bin/bash
trap 'echo "HUP: sozlamani qayta o'"'"'qidim"' HUP
trap 'echo "TERM: toza to'"'"'xtayapman"; exit 0' TERM
echo "xizmat ishga tushdi"
while true; do sleep 0.2; done
EOF
chmod +x xizmat.sh
Terminal
sleep 300 &
PID=$!
ps -o stat=,comm= -p "$PID"
kill "$PID"
Natija
S+   sleep
UstunMa'no
PIDJarayon raqami
PPIDOta jarayon raqami
STATHolati
USEREgasi
%CPU, %MEMResurs ulushi
COMMANDBuyruq

STAT ustunidagi harflar:

KodHolat
RIshlayapti yoki navbatda
SUxlayapti - hodisa kutmoqda (eng ko'p uchraydigan)
DUzilmas uyqu - odatda disk kutmoqda
ZZombi - tugagan, lekin otasi natijani olmagan
TTo'xtatilgan (Ctrl+Z yoki SIGSTOP)
+Old planda (foreground) - yuqoridagi S+ shundan
sSessiya yetakchisi
D holati - kill ishlamaydi

Uzilmas uyquda turgan jarayonni hech qanday signal uyg'otmaydi, SIGKILL ham.

Sabab: u yadro ichida, masalan javob bermayotgan NFS serveridan yoki nosoz diskdan o'qishni kutmoqda. Jarayon faqat o'sha amal tugagach signal oladi.

Serverda ko'p D holatidagi jarayon ko'rsangiz, muammo jarayonlarda emas - diskda yoki tarmoqda. dmesg va iostat ga qarang (11 va 14-bo'limlar).

ps ning ikki uslubi #

ps da ikkita tarixiy sintaksis bor va ikkalasi ham ishlaydi:

UslubBuyruqNatija
BSDps auxBarcha jarayonlar, keng ustunlar
UNIXps -efBarcha jarayonlar, ota-ona bilan
Tanlabps -o pid,ppid,stat,commFaqat kerakli ustunlar
Daraxtps -ejH yoki pstreeIerarxiya

Skriptlarda uchinchisi afzal - chiqishi barqaror va tor:

Terminal
sleep 300 &
PID=$!
ps -o user=,ni=,pri=,comm= -p "$PID"
kill "$PID"
Natija
husanboy   0  19 sleep

pgrep va pkill - nom bo'yicha #

ps aux | grep nginx iborasi ishlaydi, lekin u o'zining grep jarayonini ham topadi. pgrep bu muammodan xoli.

Terminal
sleep 400 & sleep 401 & sleep 402 &
pgrep -c -x sleep
pkill -x sleep
pgrep -c -x sleep
Natija
3
0
BuyruqVazifa
pgrep -x nomAniq nom bo'yicha PID
pgrep -f "naqsh"To'liq buyruq satri bo'yicha
pgrep -u husanboyFoydalanuvchi bo'yicha
pgrep -cFaqat sonini
pkill -x nomSignal yuborish
pidof nginxBir qatorda barcha PID
pkill -f - eng xavfli bayroq

pkill -f butun buyruq satri bo'yicha moslikni qidiradi.

Terminal
pkill -f python

Bu buyruq satrida python so'zi uchraydigan hamma jarayonni o'ldiradi - dastur nomi python bo'lmasa ham:

JarayonO'ladimi
python3 ilova.pyHa - kutilgan
tail -f /var/log/python.logHa - kutilmagan
vim python_skript.pyHa - saqlanmagan o'zgarishlar bilan
grep python /etc/passwdHa

To'g'ri tartib:

QadamBuyruq
1. Avval ko'ringpgrep -af python
2. Ro'yxatni tekshiringKutilganmi?
3. Keyin yuboringpkill -f python

pgrep -a topilgan jarayonlarning to'liq buyrug'ini ko'rsatadi - pkill dan oldin doim shuni bajaring.

Signallar #

Jarayonni to'xtatishning uch bosqichi SIGTERM (15) "Iltimos, tugat" Dastur uni USHLAY OLADI Faylni saqlaydi, ulanishni yopadi, qulfni bo'shatadi kill PID - standart SIGHUP (1) "Sozlamani qayta o'qi" Asli: terminal uzildi Bugun: xizmatlar buni "reload" deb qabul qiladi nginx -s reload shunday SIGKILL (9) "Yadro, uni o'chir" Dastur USHLAY OLMAYDI Hech nima saqlanmaydi Ma'lumot yo'qolishi mumkin FAQAT oxirgi chora To'g'ri tartib 1. kill PID - TERM yuboring va bir necha soniya kuting 2. Hali ham tirikmi? Nima uchun ekanini tekshiring - jurnalga qarang 3. Faqat shundan keyin kill -9 PID Darhol -9 yuborish: ma'lumotlar bazasi buzilishi, yarim yozilgan fayl, bo'shatilmagan qulf va "nega bu yerda .pid fayl qoldi?" degan savol.
SIGKILL muammoni hal qilmaydi - u muammoni yashiradi
Terminal
for s in HUP INT QUIT KILL TERM USR1 STOP CONT; do
    printf '%s=%s ' "$s" "$(kill -l "$s")"
done
echo
Natija
HUP=1 INT=2 QUIT=3 KILL=9 TERM=15 USR1=10 STOP=19 CONT=18

Signal ushlanadimi - tajriba #

Yuqoridagi xizmat.sh ikkita signalni ushlaydi. Uni ishga tushirib, HUP va TERM yuboramiz:

Terminal
./xizmat.sh > log.txt 2>&1 &
PID=$!
sleep 0.4; kill -HUP "$PID"
sleep 0.4; kill -HUP "$PID"
sleep 0.4; kill -TERM "$PID"
sleep 0.5
cat log.txt
Natija
xizmat ishga tushdi
HUP: sozlamani qayta o'qidim
HUP: sozlamani qayta o'qidim
TERM: toza to'xtayapman

Dastur ikkala HUP ni ham ushladi va ishlashda davom etdi, TERM da esa o'zi chiqishga qaror qildi.

Endi SIGKILL:

Terminal
./xizmat.sh > log2.txt 2>&1 &
PID=$!
sleep 0.4
{ kill -KILL "$PID"; wait "$PID"; } 2>/dev/null
cat log2.txt
kill -0 "$PID" 2>/dev/null && echo "hali tirik" || echo "o'ldi"
Natija
xizmat ishga tushdi
o'ldi

Hech qanday "to'xtayapman" xabari yo'q - dastur SIGKILL haqida umuman xabar topmaydi. Yadro uni shunchaki xotiradan olib tashlaydi.

kill -0 - signal yubormasdan tekshirish

kill -0 PID hech qanday signal yubormaydi. U faqat jarayon mavjudmi va sizda unga signal yuborish huquqi bormi degan savolga javob beradi.

Skriptlarda bu eng toza tekshiruv usuli:

UsulMuammosi
ps -p PID > /dev/nullQo'shimcha jarayon ishga tushadi
pgrep -x nomBir nechta mos kelishi mumkin
kill -0 PIDTez va aniq
[ -d /proc/PID ]Ham ishlaydi, lekin Linuxga xos

19-bo'limdagi zaxira skriptida kill -0 bilan oldingi nusxa hali ishlayotganini tekshiramiz.

Bir necha jarayon: ota va bola #

Terminal
bash -c 'sleep 300 & echo "$$ $!" > pidlar.txt; wait' &
sleep 0.4
OTA=$(cut -d' ' -f1 pidlar.txt); BOLA=$(cut -d' ' -f2 pidlar.txt)
test "$(ps -o ppid= -p "$BOLA" | tr -d ' ')" = "$OTA" && echo "ota to'g'ri"
kill "$BOLA" "$OTA" 2>/dev/null
Natija
ota to'g'ri
Ota o'lsa, bola qolib ketadi

Ota jarayon tugasa, uning bolalari o'lmaydi - ular init (PID 1) ga "asrab olinadi".

Serverdagi tipik oqibat: siz skriptni Ctrl+C bilan to'xtatasiz, lekin u ishga tushirgan ffmpeg yoki rsync ishlashda davom etadi va diskni to'ldiradi.

Yechim - jarayonlar guruhiga signal yuborish:

UsulIzoh
kill -TERM -PGIDGuruhga (PID oldida minus)
trap 'kill 0' EXITSkript chiqishda bolalarini o'ldiradi
systemd xizmatiEng ishonchli - butun cgroup to'xtaydi

Oxirgisi 12-bo'limning asosiy sabablaridan biri: systemd xizmatni cgroup ichida ushlaydi va stop da hech bir bola qolib ketmaydi.

Zombi va yetim #

Terminal
ps -eo stat= | grep -c '^Z' || true
Natija
0
TurNima bo'lganXavfli emasmi
Zombi (Z)Bola tugagan, ota wait() chaqirmaganBittasi - yo'q; minglab - ha
YetimOta tugagan, bola davom etyaptiOdatda me'yoriy
Zombini "o'ldirib" bo'lmaydi

Zombi allaqachon o'lgan. U jadvalda faqat chiqish kodini saqlab turibdi - otasi uni so'raguncha.

kill -9 zombi ustida hech qanday ta'sir qilmaydi.

To'g'ri yechim - otasini to'g'rilash yoki qayta ishga tushirish. Ota o'lgach, zombi init ga o'tadi va u darhol wait() chaqirib, jadvalni tozalaydi.

Konteynerlarda bu ko'p uchraydi: agar PID 1 sifatida oddiy dastur ishlasa, u zombilarni yig'ishtirmaydi. Shu sababli docker run --init yoki tini kabi vositalar mavjud.

Ustuvorlik: nice va renice #

Terminal
nice -n 10 sleep 300 &
PID=$!
sleep 0.2
ps -o ni= -p "$PID" | tr -d ' '
renice -n 15 -p "$PID" > /dev/null
ps -o ni= -p "$PID" | tr -d ' '
kill "$PID"
Natija
10
15
QiymatMa'no
-20Eng yuqori ustuvorlik (faqat root)
0Standart
19Eng past - "boshqalar oldin"
Zaxira nusxani nice bilan ishga tushiring

Kechasi ishlaydigan zaxira skripti diskni va protsessorni band qiladi. Agar shu payt sayt ham ishlayotgan bo'lsa, foydalanuvchilar sekinlashuvni sezadi.

Yechim - ikkita bayroq:

Terminal
nice -n 19 ionice -c 3 tar -czf /var/backups/sayt.tar.gz /var/www
BuyruqNimani pasaytiradi
nice -n 19Protsessor ustuvorligi
ionice -c 3Disk ustuvorligi (idle sinfi)

Ikkinchisi ko'pincha muhimroq: zaxira nusxa protsessorni emas, diskni band qiladi.

Fon rejimida ishga tushirish #

UsulTerminal yopilganda
buyruq &O'ladi (SIGHUP)
nohup buyruq &Yashaydi, chiqish nohup.out ga
setsid buyruqYangi sessiya - yashaydi
tmux ichidaYashaydi va qaytib kirish mumkin
systemd xizmatiTo'g'ri usul
Terminal
setsid sleep 300 > /dev/null 2>&1 < /dev/null &
sleep 0.4
pgrep -c -x sleep
pkill -x sleep
Natija
1
Uzoq ishni SSH sessiyasida qoldirmang

Ma'lumotlar bazasi migratsiyasi, katta rsync, tizim yangilanishi - bularning barchasi soatlab davom etishi mumkin.

Agar ulanish uzilsa (Wi-Fi, noutbuk uxlashi, provayder), SIGHUP keladi va ish yarmida to'xtaydi. Yarim bajarilgan migratsiya - ma'lumotlar bazasini tiklashdan ham yomonroq holat.

Har doim tmux ichida ishga tushiring:

Terminal
tmux new -s migratsiya
# buyruqni ishga tushiring, keyin Ctrl+b d bilan ajraling

Yoki bir martalik ish uchun:

Terminal
systemd-run --unit=migratsiya --collect /yo'l/skript.sh

Ikkinchisi 12-bo'limdagi systemd mexanizmini bir martalik vazifa uchun ishlatadi - jurnal ham avtomatik yoziladi.

Jarayon nima qilayotganini bilish #

SavolBuyruq
Qaysi fayllarni ochganlsof -p PID yoki ls -l /proc/PID/fd
Qaysi katalogdareadlink /proc/PID/cwd
Qaysi buyruq bilantr '\0' ' ' < /proc/PID/cmdline
Qancha xotiragrep VmRSS /proc/PID/status
Qaysi tizim chaqiruvidastrace -p PID
Kim ishga tushirganps -o user=,ppid= -p PID
Terminal
sleep 300 &
PID=$!
tr '\0' ' ' < /proc/"$PID"/cmdline; echo
grep -c VmRSS /proc/"$PID"/status
kill "$PID"
Natija
sleep 300 
1
Amaliy topshiriq
  1. ps -o bilan faqat kerakli ustunlarni chiqaring.
  2. STAT ustunidagi beshta kodni tushuntiring.
  3. pgrep -a bilan jarayonlarni avval ko'ring, keyin pkill qiling.
  4. kill -l bilan signal raqamlarini oling.
  5. trap bilan HUP ni ushlaydigan skript yozing.
  6. Unga HUP, keyin TERM, keyin KILL yuboring - farqni ko'ring.
  7. kill -0 bilan jarayon tirikligini tekshiring.
  8. nice va renice bilan ustuvorlikni o'zgartiring.
  9. setsid bilan sessiyadan mustaqil jarayon yarating.
  10. /proc/PID/ dan uchta ma'lumotni oling.

Xulosa #

  • STAT da D - uzilmas uyqu, unga kill -9 ham ta'sir qilmaydi.
  • Skriptlarda ps -o bilan aniq ustunlarni so'rang.
  • pkill -f dan oldin doim pgrep -af bilan ko'ring.
  • SIGTERM - iltimos, SIGHUP - qayta o'qi, SIGKILL - yadro o'chiradi.
  • SIGKILL ni ushlab bo'lmaydi va u hech nima saqlamaydi.
  • Avval kill, kuting, faqat keyin kill -9.
  • kill -0 - signal yubormasdan mavjudlikni tekshirish.
  • Ota o'lsa bola qoladi - guruhga signal yuboring yoki systemd ishlating.
  • Zombini o'ldirib bo'lmaydi - otasini to'g'rilang.
  • Uzoq ishni tmux yoki systemd-run ichida bajaring.

Keyingi bo'limda resurslarni ko'ramiz: protsessor yuklamasi, xotira va serverning haqiqiy holati.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.