Сколько времени до SIGKILL
Я попытался выяснить, сколько времени дается приложению для завершения при получении SIGTERM, прежде чем оно отправит SIGKILL?
Мои знания об этом сигнале очень низкие. Я читал некоторые из них в предлагаемых ответах по Stackru, но я не могу получить представление о "приблизительно", сколько времени процесс может прожить до того, как SIGTERmination.
РЕДАКТИРОВАТЬ: скажем, например, что я создаю проблему, которая намеренно блокирует закрытие ОС (возможно, while(1)
мог это сделать?)
Я ищу ответ для процесса без MMI, в стандартном дистрибутиве Linux, скажем, Ubuntu с ядром 3.x.
Я думаю, что нет времени ожидания. Если процесс исчезает, система дает ему время высвободить свои ресурсы. В противном случае система убивает его.
1 ответ
Скажем, например, что я создаю проблему, которая намеренно блокирует выключение ОС (может быть, какое-то время (1) может это сделать?)
Нету. Это не сработает. Процесс не может игнорировать некоторые сигналы, такие как SIGKILL и SIGSTOP, за исключением init
,
В общем, вы можете отправить SIGKILL сразу после SIGTERM: нет стандартной задержки, позволяющей завершить приложение. Тем не менее, разумно дать такому приложению возможность аккуратно закрыть себя, прежде чем ядро сделает это без дальнейших уведомлений.
Больше информации здесь.
Что касается процедуры выключения системы, это немного другое. Действительно, это init
система, которая решает, как и когда действовать; ОС помогает демону init в этой операции, но косвенно (доставка сигналов, очистка ресурсов и т. д.).
Таким образом, оказывается, что это зависит от реализации. Анализируя systemd-217, он, кажется, ждет 10 секунд после отправки SIGTERM.
Из src/core/shutdown.c в main
log_info("Sending SIGTERM to remaining processes...");
broadcast_signal(SIGTERM, true, true);
log_info("Sending SIGKILL to remaining processes...");
broadcast_signal(SIGKILL, true, false);
Из src/core/killall.c в broadcast_signal
killall(sig, pids, send_sighup);
[...]
if (wait_for_exit)
wait_for_children(pids, &mask);
Продолжая, в wait_for_children
until = now(CLOCK_MONOTONIC) + TIMEOUT_USEC;
[...]
k = sigtimedwait(mask, NULL, &ts);
if (k != SIGCHLD)
где TIMEOUT_USER
является #define TIMEOUT_USEC (10 * USEC_PER_SEC)
Как вы можете видеть, systemd ожидает SIGCHLD, который будет указывать на то, что дочерний процесс завершен, потому что большинство запущенных процессов являются дочерними для systemd.