Надіслати kill -9 до процесу не вимагає співпраці процесу (наприклад, обробка сигналу), це просто вбиває його.
Ви припускаєте, що через те, що деякі сигнали можуть бути захоплені та проігноровані, усі вони передбачають співпрацю. Але відповідно до цього man 2 signal
, " сигнали SIGKILL і SIGSTOP не можна вловлювати або ігнорувати". SIGTERM може бути спійманий, тому звичайний kill
не завжди ефективний - як правило, це означає, що в обробнику процесу пішло не так. 1
Якщо процес не (або не може) визначити обробник для даного сигналу, ядро виконує дію за замовчуванням. У випадку SIGTERM і SIGKILL це припинення процесу (якщо його PID не дорівнює 1; ядро не закінчиться init
) 2, що означає, що його файлові ручки закриті, пам'ять повернута в системний пул, його батько отримує SIGCHILD, його сироту діти успадковуються інітом і т. д. так само, як ніби він покликав exit
(див. man 2 exit
). Процес більше не існує - якщо тільки він не закінчується зомбі, в цьому випадку він все ще перерахований в таблиці процесора ядра з деякою інформацією; це відбувається, коли його батько цього не робитьwait
і правильно поводитися з цією інформацією. Однак у зомбі-процесах більше немає виділеної їм пам’яті, і тому вони не можуть продовжувати виконувати.
Чи є щось на зразок глобальної таблиці в пам'яті, де Linux зберігає посилання на всі ресурси, зайняті процесом, і коли я "вбиваю" процес, Linux просто проходить через цю таблицю і звільняє ресурси один за одним?
Я думаю, що це досить точно. Фізична пам’ять відстежується за сторінками (одна сторінка зазвичай дорівнює шмату в 4 КБ), і ці сторінки беруться з і повертаються в глобальний пул. Трохи складніше те, що деякі звільнені сторінки кешуються у випадку, якщо дані, які вони містять, знову потрібні (тобто дані, які були прочитані з ще існуючого файлу).
Manpages говорять про "сигнали", але, безумовно, це лише абстракція.
Звичайно, всі сигнали - це абстракція. Вони концептуальні, як і "процеси". Я трохи граю в семантику, але якщо ви маєте на увазі, що SIGKILL якісно відрізняється від SIGTERM, то так і ні. Так, у тому сенсі, що його не можна зловити, але ні в тому сенсі, що вони є обома сигналами. За аналогією, яблуко не є апельсином, але яблука та апельсини, згідно заздалегідь визначеного визначення, є і фруктами. SIGKILL здається більш абстрактним, оскільки ви не можете його зловити, але це все-таки сигнал. Ось приклад поводження з системою SIGTERM, я впевнений, що ви їх бачили і раніше:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
void sighandler (int signum, siginfo_t *info, void *context) {
fprintf (
stderr,
"Received %d from pid %u, uid %u.\n",
info->si_signo,
info->si_pid,
info->si_uid
);
}
int main (void) {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = sighandler;
sa.sa_flags = SA_SIGINFO;
sigaction(SIGTERM, &sa, NULL);
while (1) sleep(10);
return 0;
}
Цей процес просто спатиме вічно. Ви можете запустити його в терміналі і надіслати його SIGTERM kill
. Він випльовує такі речі, як:
Received 15 from pid 25331, uid 1066.
1066 - мій UID. PID - це оболонка оболонки, з якої kill
виконується, або PID вбивства, якщо ви розщедрили його ( kill 25309 & echo $?
).
Знову ж таки, немає сенсу встановлювати обробник для SIGKILL, оскільки він не працюватиме. 3 Якщо я kill -9 25309
процес закінчуватимуться. Але це все-таки сигнал; в ядрі є інформація про те, хто подав сигнал , який це сигнал тощо.
1. Якщо ви не переглянули список можливих сигналів , див kill -l
.
2. Інший виняток, як згадує Тім Пост нижче, стосується процесів у режимі безперебійного сну . Їх неможливо прокинути, поки не буде вирішено основну проблему, і таким чином не буде відкладено ВСІ сигнали (включаючи SIGKILL) на тривалість. Однак процес не може створити цю ситуацію спеціально.
3. Це не означає, що використання kill -9
на практиці краще робити. Мій обробник прикладу поганий у тому сенсі, до якого він не призводить exit()
. Справжня мета обробника SIGTERM - надати процесу можливість виконувати такі дії, як очищення тимчасових файлів, а потім добровільно вийти. Якщо ви користуєтеся kill -9
, це не дає цього шансу, тому робіть це лише тоді, якщо частина "виходу добровільно", здається, не вдалася.
kill -9
довідка .