Отправка kill -9 процессу не требует взаимодействия процесса (например, обработки сигнала), она просто убивает его.
Вы предполагаете, что, поскольку некоторые сигналы могут быть уловлены и проигнорированы, все они связаны с сотрудничеством. Но согласно man 2 signal
« сигналы SIGKILL и SIGSTOP не могут быть пойманы или проигнорированы». SIGTERM может быть пойман, поэтому plain kill
не всегда эффективна - обычно это означает, что что-то в обработчике процесса не работает. 1
Если процесс не (или не может) определить обработчик для данного сигнала, ядро выполняет действие по умолчанию. В случае SIGTERM и SIGKILL это должно завершить процесс (если его PID не равен 1; ядро не будет завершено init
) 2 означает, что его файловые дескрипторы закрыты, его память возвращена в системный пул, его родитель получает SIGCHILD, его сирота дети наследуются init и т. д., как если бы он вызвал 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, если вы его разветвляете ( kill 25309 & echo $?
).
Опять же, нет смысла устанавливать обработчик для SIGKILL, потому что он не будет работать. 3 Если я kill -9 25309
закончу процесс. Но это все еще сигнал; ядро имеет информацию о том, кто послал сигнал , что это за сигнал и т. д.
1. Если вы еще не посмотрели список возможных сигналов , смотрите kill -l
.
2. Другое исключение, как упоминает Тим Пост ниже, относится к процессам в непрерывном сне . Они не могут быть разбужены до тех пор, пока не будет решена основная проблема, и поэтому все сигналы (включая SIGKILL) будут отложены на время. Однако процесс не может специально создать такую ситуацию.
3. Это не означает, kill -9
что лучше использовать на практике. Мой примерный обработчик плох в том смысле, что он не приводит к exit()
. Настоящая цель обработчика SIGTERM - дать процессу возможность выполнять такие вещи, как очистка временных файлов, а затем добровольно завершать работу. Если вы используете kill -9
, у вас не будет такого шанса, так что делайте это только в том случае, если часть «добровольно выйти», похоже, не удалась.
kill -9
ссылка .