systemd 停止命令实际上是如何工作的?

107

我正在使用一个systemd服务,当它被“启动”时调用一个进程(例如systemctl start test.service)。根据设计,该进程将永远循环运行,我们可以使用ps命令查看该进程的存在。我们也看到,对于systemctl stop命令,该进程被杀死了(如预期)。 但是,我们的要求是在进程被杀死之前从进程内部执行一些安全关闭操作。但我不知道如何从进程内部检测到systemd停止操作。

systemctl stop test.service命令是否发送SIGKILLSIGTERM信号以杀死进程?我如何在进程内检测到systemctl stop操作?

2个回答

149

默认情况下,会发送一个SIGTERM信号,等待90秒后再发送一个SIGKILL信号。

使用systemd杀死进程非常可定制并且有很好的文档记录。

我建议阅读所有man systemd.kill,并阅读关于man systemd.service中的ExecStop=内容

要响应这些信号,请参考您正在使用的语言的信号处理文档。


5
值得注意的是:如果主进程在超时之前停止,systemd会向所有剩余的子进程发送SIGKILL信号。如果达到了超时时间,它将向整个控制组发送SIGKILL信号。 - Steen Schütt
您可以使用 KillMode https://www.freedesktop.org/software/systemd/man/systemd.kill.html#KillMode= 来调整主进程的子进程所需执行的操作。默认行为是在主进程结束时杀死任何剩余的子进程 (因为通常这是为了释放所有泄漏的资源,因为良好的主进程在等待所有子进程停止之前不会结束 wait():n)。 - Mikko Rantalainen

4
一个 systemctl stop test.service 命令会发送SIGTERM信号来终止进程,系统会将SIGTERM信号发送给进程,进程可以通过信号注册来捕获信号。例如,可以像下面这样注册SIGTERM信号:
void signal_callback()
{
    printf("Process is going down\n");
}
signal(SIGTERM, signal_callback)

当进程收到 SIGTERM 信号时,会执行 signal_callback() 函数。


2
请注意,以下是所发生情况的伪代码。通常在信号处理程序中进行任何文件IO(例如printf)都是危险的。如果您只关心打印消息,然后可能会崩溃,那没问题。但是,如果您想正确处理信号,则信号处理程序应仅设置线程安全变量(例如std :: atomic <bool>),而主事件循环则应监视该线程安全变量。 - Mark Lakata

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接