Den*_*ain 6 linux process-management systemd daemon
如何systemd
处理托管进程的子进程的死亡?
假设systemd
启动守护进程foo
,然后启动其他三个守护进程:bar1
,bar2
,和bar3
。systemd
对foo
ifbar2
意外终止会做些什么吗?根据我的理解,foo
如果您没有startd
通过更改属性进行其他说明,则在 Solaris 上的服务管理工具 (SMF) 下将被终止或重新启动ignore_error
。难道systemd
不同的表现?
编辑#1:
我编写了一个测试守护进程来测试systemd
的行为。守护进程被调用mother_daemon
是因为它产生子进程。
#include <iostream>
#include <unistd.h>
#include <string>
#include <cstring>
using namespace std;
int main(int argc, char* argv[])
{
cout << "Hi! I'm going to fork and make 5 child processes!" << endl;
for (int i = 0; i < 5; i++)
{
pid_t pid = fork();
if (pid > 0)
{
cout << "I'm the parent process, and i = " << i << endl;
}
if (pid == 0)
{
// The following four lines rename the process to make it easier to keep track of with ps
int argv0size = strlen(argv[0]);
string childThreadName = "mother_daemon child thread PID: ";
childThreadName.append( to_string(::getpid()) );
strncpy(argv[0],childThreadName.c_str(),argv0size + 25);
cout << "I'm a child process, and i = " << i << endl;
pause();
// I don't want each child process spawning its own process
break;
}
}
pause();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是由一个systemd
名为的单元控制的mother_daemon.service
:
[Unit]
Description=Testing how systemd handles the death of the children of a managed process
StopWhenUnneeded=true
[Service]
ExecStart=/home/my_user/test_program/mother_daemon
Restart=always
Run Code Online (Sandbox Code Playgroud)
该mother_daemon.service
装置由以下控制mother_daemon.target
:
[Unit]
Description=A target that wants mother_daemon.service
Wants=mother_daemon.service
Run Code Online (Sandbox Code Playgroud)
当我运行sudo systemctl start mother_daemon.target
(之后sudo systemctl daemon-reload
)时,我可以看到父守护进程和五个子守护进程。
杀死其中一个孩子对父母没有影响,但杀死父母(从而触发重新启动)确实会重新启动孩子。
停止mother_daemon.target
与sudo systemctl stop mother_daemon.target
结束孩子们。
我认为这回答了我的问题。
主进程以正常方式处理其子进程的死亡。
这就是 POSIX 世界。如果进程A已经分叉了B,并且进程B已经分叉了C、D和E;那么进程 B 是从 C、D 和 E 的终止中看到的SIGCHLD
和wait()
状态。进程 A 不知道 C、D 和 E 发生了什么,这与 systemd 无关。
要让 A 知道 C、D 和 E 终止,必须发生两件事。
service-manager
。exit()
。服务愚蠢,错误和徒劳地尝试“守护进程”自己做到这一点。(人们可以kevent()
在 BSD 上变得聪明。但这是一个 Linux 问题。)