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메인 프로세스라는 개념이 있습니다. 시스템 문서에서는 이를 "주 서비스 프로세스" 또는 간단히 "주 프로세스"라고 합니다.

예제 4에서는systemd.service 문서계산의 주요 과정이 소개됩니다 Type=forking.

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

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

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

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

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

관련 정보