systemd 如何处理托管进程的子进程的死亡?

Den*_*ain 6 linux process-management systemd daemon

如何systemd处理托管进程的子进程的死亡?

假设systemd启动守护进程foo,然后启动其他三个守护进程:bar1bar2,和bar3systemdfooifbar2意外终止会做些什么吗?根据我的理解,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.targetsudo systemctl stop mother_daemon.target结束孩子们。

我认为这回答了我的问题。

Jde*_*eBP 5

它没有。

主进程以正常方式处理其子进程的死亡。

这就是 POSIX 世界。如果进程A已经分叉了B,并且进程B已经分叉了C、D和E;那么进程 B 是从 C、D 和 E 的终止中看到的SIGCHLDwait()状态。进程 A 不知道 C、D 和 E 发生了什么,这与 systemd 无关。

要让 A 知道 C、D 和 E 终止,必须发生两件事。

(人们可以kevent()在 BSD 上变得聪明。但这是一个 Linux 问题。)