오픈 소스/LXC

[LXC] 더블포크(double fork) - 좀비 프로세스 피하는 방법

benjykim 2019. 5. 7. 21:19
반응형

lxc-monitor.c - double fork 사용

 

  • 사람들이 하는 흔한 실수 중 하나는, 자식 프로세스의 종료를 기다리는 waitpid()를 호출하지 않고 자식 프로세스를 포크하는 것이다. wait()호출을 하지 않으면, 자식 프로세스는 종료 후 좀비 프로세스가 된다. 왜냐하면 그것(자식)의 부모 프로세스가 시스템에서 자식의 프로세스 정보를 cleanup 하지 않기 때문이다. 좀비 프로세스가 시스템의 PID를 차지하므로 시스템에서 사용가능한 PID를 줄인다. 좀비는 ps명령으로 프로세스를 확인하면 '비활성화됨(defunct)'로 표시된다.
  • 그러나 때로는 부모 프로세스가 자식 프로세스를 오랫동안 기다리지 않는 것을 원한다. '좀비 프로세스를 만들지 않기', '자식 프로세스가 종료 될 때까지 기다리지 말기'를 모두 달성할 수 있는 방법이 있는데, 그 방법이 바로 double fork하는 것이다.
  • 부모 프로세스(예 : A)가 자식 프로세스를 '무언가'로 fork하고자 할 때 간단한 아이디어가 있다. 프로세스 A는 '무언가'를 직접 수행하는 프로세스를 fork하지 않는다. 프로세스 A는 먼저 하위 프로세스(예 : B)를 분기한 다음 프로세스는 자식 프로세스(예 : C)를 '무언가'로 포크하고 프로세스 B는 프로세스 C가 만들어 지자 마자 종료한다.
  • 이런식으로, 프로세스 A는 단지 짧은 시간 동안 프로세스 B를 기다리면 된다. 같은 시간에 부모 프로세스가 없으므로(프로세스 B가 죽음(dead)), 시스템은 프로세스 C를 초기화 프로세스에 'rechild'한다. init 프로세스는 자식 프로세스에 wait()를 호출하여 좀비 프로세스 문제를 해결한다.
void func()
{
     pid_t pid1;
     pid_t pid2;
     int status;

     if (pid1 = fork()) {
             /* parent process A */
             waitpid(pid1, &status, NULL);
     } else if (!pid1) {
             /* child process B */
             if (pid2 = fork()) {
                     exit(0);
             } else if (!pid2) {
                     /* child process C */
                     execvp("something");
             } else {
                     /* error */
             }
     } else {
             /* error */
     }
}
  • 궁금한 것 두가지

    1. 부모가 먼저 죽는 경우 어떻게 되나?

      • 부모가 먼저 죽으면 자식은 고아가 되고, 이 고아 프로세스들은 init 프로세스의 자식이 된다. 즉, 자식이 살아있는데 부모가 죽으면, 자식의 부모가 init 프로세스로 자동 변경된다.
    2. 자식이 waitpid() 호출 전에 죽으면 어떻게 되나?

      • 자식이 먼저 죽었는데 부모가 waitpid()로 이를 해제해주지 않으면 좀비 프로세스가 되고, 그 후 waitpid()를 호출하는 순간 바로 리턴되면서 자식의 리소스가 해제된다.
  • 결국 정리해보면 다음과 같다.

    1. A 프로세스는 fork 하여 자식 프로세스 B를 만든다.
    2. B프로세스는 다시 fork 하여 자식 프로세스 C를 만든다.
    3. B프로세스는 C가 만들어지자 마자 종료하고, 프로세스 C는 부모 프로세스(B)가 죽었기 때문에 부모가 init으로 변경된다.
    4. A 프로세스는 자식 프로세스 B를 waitpid()를 통해 정상적으료 종료시킨다.
  • 참고

반응형

'오픈 소스 > LXC' 카테고리의 다른 글

[LXC] lxc-monitor.c 분석  (0) 2019.05.09
[LXC] 수동 설치 - lxc-net 오류 해결  (0) 2019.04.16