1. UNIX에서 프로세스의 생성

fork() 시스템 호출은 새로운 프로세스를 만들어내는 기능을 한다.
새로운 프로세스는 원래의 프로세스 주소 공간의 복사본을 가지고 있다.
fork() : 현재 돌아가고 있던 프로세스를 복사해서 다른 프로세스를 만든다.
exec() : 프로세스로 하여금 다른 바이너리를 가지고 새로 시작하도록 한다. 자식 프로세스는 exec을 통해 내용을 모두 바꾼다.

 

2. 프로세스 삭제

프로세스는 마지막 statement를 실행하고 exit() 시스템 호출을 이용하여 운영체제로 하여금 삭제하도록 한다.
부모는 자식에게서 wait을 통해 상태 값을 받을 수 있다.

3. 좀비 프로세스

1. 좀비 프로세스란?

자식 process가 종료되어 자원 해제를 요청했는데 부모 프로세스가 자식 프로세스의 종료 상태를 받아들이지 못해서 프로세스 테이블에 남아 있는 상황이다. 그래서 죽었지만 살아있는 '좀비'와 같은 상태가 된다. 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
 
 
int main() {
     
    pid_t childPid;
     
    childPid = fork();
     
    if(childPid > 0) {  // 부모 프로세스
        printf("부모 PID : %ld, pid : %d\n",(long)getpid(), childPid);
        sleep(30);
        printf("부모 종료\n");
        exit(0);
    }
    else if(childPid == 0){  // 자식 코드
        printf("자식 시작 PID : %ld\n", (long)getpid());
        sleep(1);
        printf("자식 종료\n");
        exit(0);
    }
    else {  // fork 실패
        perror("fork Fail! \n");
        return -1;
    }
     
    return 0;
}

 

2. 좀비 프로세스의 목적

좀비상태의 목적은 나중에 parent process가 가져갈 child에 대한 정보를 유지하는 것이다. 이 정보는 자식의 프로세스 ID와 종료 상태 및 자식의 자원 사용률(CPU 시간, 메모리 등) 등을 포함하고 있다.

 

3. 좀비 프로세스가 생겼을 때 제거되는 과정

만약 프로세스가 종료하고 좀비 상태에 있는 자식을 가지고 있으면, 모든 좀비 자식의 어버이 프로세스 ID는 1(init 프로세스)로 바뀌며, 그 프로세스는 자식을 넘겨받아 청소한다. 즉, 좀비를 제거한다 (init은 그들을 wait 한다).

 

4. 좀비 프로세스가 생기지 않도록 처리

그렇다면 좀비프로세스는 어떻게 처리할까? 좀비 프로세스를 내버려 두어서는 안 된다. 좀비는 커널의 공간을 차지하므로, 궁극에는 프로세스를 더 만들 수 없게 된다. 자식을 fork()할 때마다 자식이 좀비가 되는 것을 방지하기 위해 반드시 자식을 wait 해야 한다. 이렇게 하기 위하여 SIGCHLD 신호를 포착하는 신호 처리기를 설정하여 그 신호 처리기 안에서 wait를 호출한다.

Signal(SIGCHLD, sig_chld);

 

4. 고아 프로세스 (Orphan process)

부모 process가 먼저 종료 → 고아 프로세스의 부모 프로세스 PID=1로 변경 (init 프로세스)

 

 

 

 

Reference

- [프로세스 생성]

- [좀비  프로세스 처리] UNIX Network Programming 3rd edition 책

 

 

+ Recent posts