systemd는 관리 프로세스의 자식 사망을 어떻게 처리합니까?

systemd는 관리 프로세스의 자식 사망을 어떻게 처리합니까?

systemd관리 프로세스의 하위 프로세스 종료를 어떻게 처리합니까 ?

systemd가 데몬을 시작한 foo다음 세 개의 다른 데몬( , 및 )을 시작 bar1한다고 bar2가정 합니다 bar3. 예기치 않게 종료되는 경우 어떻게 해야 systemd합니까 ? 제가 이해한 바에 따르면 속성을 변경하여 별도로 지정하지 않으면 Solaris의 SMF(서비스 관리 기능)가 종료되거나 다시 시작됩니다 . 다르게 행동 합니까 ?foobar2foostartdignore_errorsystemd

편집 #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;
  }

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

장치 mother_daemon.service는 다음에 의해 제어됩니다 mother_daemon.target.

[Unit]
Description=A target that wants mother_daemon.service
Wants=mother_daemon.service

sudo systemctl start mother_daemon.target(뒤에 ) 실행하면 sudo systemctl daemon-reload상위 데몬과 5개의 하위 데몬을 볼 수 있습니다.

자식 중 하나를 죽이는 것은 부모에게 아무런 영향을 주지 않지만, 부모를 죽이면(따라서 다시 시작이 시작되면) 자식이 다시 시작됩니다.

멈추면 mother_daemon.target아이들 sudo systemctl stop mother_daemon.target도 끝납니다.

나는 이것이 내 질문에 대한 답이라고 생각합니다.

답변1

그렇지 않습니다.

주요 프로세스는 일반적인 방법으로 자녀의 죽음을 처리합니다.

이것이 POSIX의 세계입니다. 프로세스 A가 B를 분기하고 프로세스 B가 C, D, E를 분기한 경우 프로세스 B 는 C, D, E의 종료로부터 상태를 보는 것입니다. 프로세스 A는 C, D, E에 무슨 일이 일어나는지 알지 못하며 이는 systemd와 무관 SIGCHLD합니다 .wait()

A가 C, D, E 종료를 인식하려면 두 가지 일이 발생해야 합니다.

kevent()( BSD에 대해 영리하게 이해할 수 있습니다 . 그러나 이것은 Linux 질문입니다.)

답변2

systemd메인 프로세스라는 개념을 가지고 있습니다. 시스템 문서에서는 이를 "주요 서비스 프로세스" 또는 간단히 "주요 프로세스"라고 합니다.

예제 4systemd.service 문서설명하면 주요 프로세스가 계산됩니다 Type=forking.

Restart=systemd.service 문서에 대한 문서기본 프로세스와 관련하여 서비스가 시작될 때의 다양한 가능성을 설명합니다.

위에 링크된 "예제 4"의 주요 텍스트는 다음과 같습니다.

systemd는 원래 프로그램이 계속 실행되는 동안 서비스가 초기화 과정에 있는 것으로 간주합니다. 성공적으로 종료되고 최소한 프로세스가 남아 있으면(RemainAfterExit=no) 서비스가 시작된 것으로 간주됩니다.

종종 전통적인 데몬은 하나의 프로세스로만 구성됩니다. 따라서 원래 프로세스가 종료된 후 하나의 프로세스만 남게 되면 systemd는 해당 프로세스를 서비스의 주요 프로세스로 간주합니다. 이 경우 $MAINPID 변수는 ExecReload=, ExecStop= 등에서 사용할 수 있습니다.

둘 이상의 프로세스가 남아 있는 경우 systemd는 기본 프로세스를 결정할 수 없으므로 기본 프로세스가 있다고 가정하지 않습니다. 이 경우 $MAINPID는 아무 것도 확장되지 않습니다. 그러나 프로세스가 기존 PID 파일을 작성하기로 결정하면 systemd는 거기에서 기본 PID를 읽을 수 있습니다. 이에 따라 PIDFile=을 설정하십시오.

관련 정보