10-bo‘lim
Jarayonlar va signallar
ps, pgrep, signallar va osilib qolgan dasturni to'g'ri - ma'lumot yo'qotmasdan - to'xtatish.
Ushbu bo‘lim mundarijasi
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 #
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
sleep 300 &
PID=$!
ps -o stat=,comm= -p "$PID"
kill "$PID"
S+ sleep
| Ustun | Ma'no |
|---|---|
PID | Jarayon raqami |
PPID | Ota jarayon raqami |
STAT | Holati |
USER | Egasi |
%CPU, %MEM | Resurs ulushi |
COMMAND | Buyruq |
STAT ustunidagi harflar:
| Kod | Holat |
|---|---|
R | Ishlayapti yoki navbatda |
S | Uxlayapti - hodisa kutmoqda (eng ko'p uchraydigan) |
D | Uzilmas uyqu - odatda disk kutmoqda |
Z | Zombi - tugagan, lekin otasi natijani olmagan |
T | To'xtatilgan (Ctrl+Z yoki SIGSTOP) |
+ | Old planda (foreground) - yuqoridagi S+ shundan |
s | Sessiya yetakchisi |
D holati - kill ishlamaydiUzilmas 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:
| Uslub | Buyruq | Natija |
|---|---|---|
| BSD | ps aux | Barcha jarayonlar, keng ustunlar |
| UNIX | ps -ef | Barcha jarayonlar, ota-ona bilan |
| Tanlab | ps -o pid,ppid,stat,comm | Faqat kerakli ustunlar |
| Daraxt | ps -ejH yoki pstree | Ierarxiya |
Skriptlarda uchinchisi afzal - chiqishi barqaror va tor:
sleep 300 &
PID=$!
ps -o user=,ni=,pri=,comm= -p "$PID"
kill "$PID"
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.
sleep 400 & sleep 401 & sleep 402 &
pgrep -c -x sleep
pkill -x sleep
pgrep -c -x sleep
3
0
| Buyruq | Vazifa |
|---|---|
pgrep -x nom | Aniq nom bo'yicha PID |
pgrep -f "naqsh" | To'liq buyruq satri bo'yicha |
pgrep -u husanboy | Foydalanuvchi bo'yicha |
pgrep -c | Faqat sonini |
pkill -x nom | Signal yuborish |
pidof nginx | Bir qatorda barcha PID |
pkill -f - eng xavfli bayroqpkill -f butun buyruq satri bo'yicha moslikni qidiradi.
pkill -f python
Bu buyruq satrida python so'zi uchraydigan hamma
jarayonni o'ldiradi - dastur nomi python bo'lmasa ham:
| Jarayon | O'ladimi |
|---|---|
python3 ilova.py | Ha - kutilgan |
tail -f /var/log/python.log | Ha - kutilmagan |
vim python_skript.py | Ha - saqlanmagan o'zgarishlar bilan |
grep python /etc/passwd | Ha |
To'g'ri tartib:
| Qadam | Buyruq |
|---|---|
| 1. Avval ko'ring | pgrep -af python |
| 2. Ro'yxatni tekshiring | Kutilganmi? |
| 3. Keyin yuboring | pkill -f python |
pgrep -a topilgan jarayonlarning to'liq buyrug'ini
ko'rsatadi - pkill dan oldin doim shuni bajaring.
Signallar #
for s in HUP INT QUIT KILL TERM USR1 STOP CONT; do
printf '%s=%s ' "$s" "$(kill -l "$s")"
done
echo
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:
./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
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:
./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"
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 tekshirishkill -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:
| Usul | Muammosi |
|---|---|
ps -p PID > /dev/null | Qo'shimcha jarayon ishga tushadi |
pgrep -x nom | Bir nechta mos kelishi mumkin |
kill -0 PID | Tez 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 #
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
ota to'g'ri
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:
| Usul | Izoh |
|---|---|
kill -TERM -PGID | Guruhga (PID oldida minus) |
trap 'kill 0' EXIT | Skript chiqishda bolalarini o'ldiradi |
systemd xizmati | Eng 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 #
ps -eo stat= | grep -c '^Z' || true
0
| Tur | Nima bo'lgan | Xavfli emasmi |
|---|---|---|
Zombi (Z) | Bola tugagan, ota wait() chaqirmagan | Bittasi - yo'q; minglab - ha |
| Yetim | Ota tugagan, bola davom etyapti | Odatda me'yoriy |
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 #
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"
10
15
| Qiymat | Ma'no |
|---|---|
-20 | Eng yuqori ustuvorlik (faqat root) |
0 | Standart |
19 | Eng past - "boshqalar oldin" |
nice bilan ishga tushiringKechasi ishlaydigan zaxira skripti diskni va protsessorni band qiladi. Agar shu payt sayt ham ishlayotgan bo'lsa, foydalanuvchilar sekinlashuvni sezadi.
Yechim - ikkita bayroq:
nice -n 19 ionice -c 3 tar -czf /var/backups/sayt.tar.gz /var/www
| Buyruq | Nimani pasaytiradi |
|---|---|
nice -n 19 | Protsessor ustuvorligi |
ionice -c 3 | Disk ustuvorligi (idle sinfi) |
Ikkinchisi ko'pincha muhimroq: zaxira nusxa protsessorni emas, diskni band qiladi.
Fon rejimida ishga tushirish #
| Usul | Terminal yopilganda |
|---|---|
buyruq & | O'ladi (SIGHUP) |
nohup buyruq & | Yashaydi, chiqish nohup.out ga |
setsid buyruq | Yangi sessiya - yashaydi |
tmux ichida | Yashaydi va qaytib kirish mumkin |
systemd xizmati | To'g'ri usul |
setsid sleep 300 > /dev/null 2>&1 < /dev/null &
sleep 0.4
pgrep -c -x sleep
pkill -x sleep
1
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:
tmux new -s migratsiya
# buyruqni ishga tushiring, keyin Ctrl+b d bilan ajraling
Yoki bir martalik ish uchun:
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 #
| Savol | Buyruq |
|---|---|
| Qaysi fayllarni ochgan | lsof -p PID yoki ls -l /proc/PID/fd |
| Qaysi katalogda | readlink /proc/PID/cwd |
| Qaysi buyruq bilan | tr '\0' ' ' < /proc/PID/cmdline |
| Qancha xotira | grep VmRSS /proc/PID/status |
| Qaysi tizim chaqiruvida | strace -p PID |
| Kim ishga tushirgan | ps -o user=,ppid= -p PID |
sleep 300 &
PID=$!
tr '\0' ' ' < /proc/"$PID"/cmdline; echo
grep -c VmRSS /proc/"$PID"/status
kill "$PID"
sleep 300
1
ps -obilan faqat kerakli ustunlarni chiqaring.STATustunidagi beshta kodni tushuntiring.pgrep -abilan jarayonlarni avval ko'ring, keyinpkillqiling.kill -lbilan signal raqamlarini oling.trapbilanHUPni ushlaydigan skript yozing.- Unga
HUP, keyinTERM, keyinKILLyuboring - farqni ko'ring. kill -0bilan jarayon tirikligini tekshiring.nicevarenicebilan ustuvorlikni o'zgartiring.setsidbilan sessiyadan mustaqil jarayon yarating./proc/PID/dan uchta ma'lumotni oling.
Xulosa #
STATdaD- uzilmas uyqu, ungakill -9ham ta'sir qilmaydi.- Skriptlarda
ps -obilan aniq ustunlarni so'rang. pkill -fdan oldin doimpgrep -afbilan ko'ring.SIGTERM- iltimos,SIGHUP- qayta o'qi,SIGKILL- yadro o'chiradi.SIGKILLni ushlab bo'lmaydi va u hech nima saqlamaydi.- Avval
kill, kuting, faqat keyinkill -9. kill -0- signal yubormasdan mavjudlikni tekshirish.- Ota o'lsa bola qoladi - guruhga signal yuboring yoki
systemdishlating. - Zombini o'ldirib bo'lmaydi - otasini to'g'rilang.
- Uzoq ishni
tmuxyokisystemd-runichida bajaring.
Keyingi bo'limda resurslarni ko'ramiz: protsessor yuklamasi, xotira va serverning haqiqiy holati.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
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.