8

我试图弄清楚在收到 SIGTERM 时,应用程序在发送 SIGKILL 之前有多少时间退出?

我对这些信号的了解非常少。我已经在 Stackoverflow 上的建议答案中阅读了其中的一些内容,但我无法大致了解一个进程在被 SIGTER 终止之前可以存活多少时间。

编辑:例如,假设我创建了一个故意阻止操作系统关闭的问题(也许while(1)可以做到?)

我正在寻找标准 Linux 发行版上没有 MMI 的进程的答案,比如带有内核 3.x 的 Ubuntu。

我的猜测是没有等待时间。如果进程消失,系统会给它时间来释放它的资源。否则,系统会杀死它。

4

1 回答 1

10

Let's say for instance that I create a problem that purposely blocks the OS from shutting down (maybe a while(1) could do it ?)

Nope. It won't work. A process may not ignore some signals such as SIGKILL and SIGSTOP, except for init.
In general, you can send SIGKILL immediately after SIGTERM: there is no standard delay to let the application terminate. However, it's wise to give such application a chance to neatly close itself before the kernel will do that without further notifications.
More information here.

What concerns the system shutdown procedure is a little different. Indeed, it is the init system that decides how and when to take action; the OS helps the init daemon in this operation but indirectly (delivering signals, cleaning up resources and so on).
So, it turns out it's implementation dependent. Analyzing systemd-217, it seems to wait for 10s after sending SIGTERM.

From src/core/shutdown.c in 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);

From src/core/killall.c in broadcast_signal

killall(sig, pids, send_sighup);
[...]
if (wait_for_exit)
            wait_for_children(pids, &mask);

Continuing, in wait_for_children

until = now(CLOCK_MONOTONIC) + TIMEOUT_USEC;
[...]
k = sigtimedwait(mask, NULL, &ts);
                if (k != SIGCHLD)

where TIMEOUT_USER is #define TIMEOUT_USEC (10 * USEC_PER_SEC)

As you can see, systemd waits for SIGCHLD which would indicate the child has terminated, because most of the processes running are systemd's children.

于 2014-12-19T19:06:59.723 回答