waitpid(2)

#include <sys/types.h>
#include <sys/wait.h>

pid_t waitpid(pid_t pid, int *status, int options);

현재 프로세스가 fork(2)한 child 프로세스의 상태 변화를 monitoring합니다. 주로 child proccess가 종료되었을 때에 많이 사용하고, child process의 종료 원인이 무엇인지를 확인합니다.

 

 만약 부모 process에서 SIGCHLD 시그널에 대해서 signal(2) 또는 sigaction(2)으로 SIG_IGN으로 설정하지 않았다면, wait(2) / waitpid(2) 등의 함수로 child 종료를 wait해야 합니다. 그렇지 않으면, 종료된 child process는 메모리에서 사라지지않고 좀비("zombie" 또는 "defunct")상태가 됩니다. zombie 상태에서는 kill 등으로 절대로 종료시킬 수 없으며, 오로지 부모 프로세스가 종료해야만 사라지게 됩니다. 따라서 SIGCHLD signal에 대해서 SIG_IGN으로 설정하거나 signal handler 함수에 wait(2)/waitpid(2)함수로 child의 process 상태를 읽어주어야 종료됩니다. 또는 주기적으로 waitpid(2)를 호출하여 wait상태인 child process의 memory를 free 시켜주어야 합니다. wait(2) / waitpid(2) 함수는 daemon 프로그램에서 child process의 개수를 유지할 때에도 많이 사용합니다. child process가 종료되었을 때에 다시 fork(2)를 한다든지 활용도가 다양합니다.

 

 ※ 좀비(zombie)프로세스는 child process가 정상 또는 비정상적으로 종료했는 데, 부모 프로세스에게 종료상태(정상종료면 main함수의 return값 또는 exit함수의 파라미터값, 비정상종료이면 signal 번호)를 전달하기 위해서 최소한의 resource로 유지하고 있는 프로세스를 말합니다. 즉, child process가 완전히 사라지면 부모 process에게 실행 결과를 전달을 할 수 없으니, 아무런 기능도 하지 않고 오로지 부모 프로세스에게 종료 메시지를 전달하기 위해서 떠 있 는 프로세스입니다. 만약 부모 프로세스가 종료가 되면 좀비프로세스의 부모프로세스가 init 프로세스인 1번으로 바뀌고 init 프로세스가 wait 또는 SIGCHLD에 대해 SIG_IGN으로 처리해버리기 때문에 zombie 프로세스는 사라집니다.

 

파라미터

 

pid
    - wait할 자식 프로세스의 유형

 -1 > pid  : 그룹ID가 절대값과 같은 차일드 프로세스를 waiting합니다.
 -1 == pid : 아무 자식 프로세스 ID라도 waiting합니다.
  0 == pid : 자신과 같은 프로세스 그룹ID를 가진 차일드 프로세스를 waiting합니다.
  0 < pid  : 넘겨진 pid인 자식 프로세스만 waiting합니다.
status
    - return된 자식 프로세스의 상태 변경값을 저장하는 변수입니다. (ouput only)
      이 상태값의 의미를 해석하는 여러가지 macro함수를 제공합니다.
    - staus의 상위 바이트는 child process의 상태 및 종료 원인이 
      하위 바이트는 상세 값을 저장되어 있습니다.
    WIF로 시작하는 macro는 상위 바이트의 상태를 판단하는 함수이며 
    나머지 macro함수는 상세 값을 읽을 수 있습니다.
    
 WIFEXITED(status) 
     - 만약 정상종료했다면. 즉, _exit(2), exit(3) 또는 main(3)함수 return으로 종료했다면.
     WEXITSTATUS(status) : WIFEXITED(status)가 0이 아닌 값일 경우
        _exit(2), exit(3)의 파라미터로 넘긴 값, 또는 main(3)함수의 return 값을 얻습니다.
        exit()나 main의 return 값이 왜 필요한 지 아시겠지요?


 WIFSIGNALED(status) 
     - 만약 시그널이 발생하여 비정상적으로 종료했다면.
     WTERMSIG(status)  : WIFSIGNALED(status)가 0이 아닌 값일 경우, signal 번호를 얻습니다.
     WCOREDUMP(status) : WIFSIGNALED(status)가 0이 아닌 값일 경우, 
                core file이 생성되었는 지 여부를 return합니다.


 WIFSTOPPED(status) 
     - 만약 stop signal이 발생하였다면. ptrace(2) 등으로 child 프로세스를 tracing중일 때.
     WSTOPSIG(status) : WIFSTOPPED(status)가 0이 아닌 값일 경우, child process를 중지 시킨 signal 번호.


 WIFCONTINUED(status) 
     - STOP되었던, 자식 프로세스가 SIGCONT로 재 실행되었다면.
option
    - 0 또는 아래의 상수의 조합으로 설정됩니다.

 0         : 결과를 return할 때까지 block합니다.
 WNOHANG   : 현재 종료된 자식 프로세스가 없으면 block하지 않고 바로 0을 반환함.
 WUNTRACED : 자식 프로세스가 STOP하면 반환함
 WCONTINUED: STOP되었던 자식 프로세스가 재 실행되면 반환함.

 

RETURN

0
    -  option이 WNOHANG인 경우 종료된 자식 프로세스가 없으면 바로 0을 return 함


0 이상
    - 상태가 변경된 자식 프로세스 ID. 
    - 파라미터 status는 return된 자식 프로세스 ID의 상태값을 저장합니다.
    - 이 함수의 호출은 자식 프로세스의 상태 변화가 있을 때까지 대기(block)합니다.
      따라서 일반적으로는 child의 상태가 변경된 signal SIGCHLD인 경우에 
      wait(2)함수를 호출하는 방식으로 처리힙니다.


-1
    - wait중 오류가 발생하였으며, 상세 오류내용은 errno 전역 변수에 설정됩니다.

 ECHILD : SIGCHLD에 대해 SIG_IGN으로 설정하여 wait할 필요가 없음
 EINTR  : SIGCHLD signal이 발생함

 


활용 예제

 

Sample

#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    pid_t pid;
    int status;
    pid = fork();  // fork로 child 프로세스를 생성함....

    ......

    pid = waitpid(pid, &status, 0); // 특정 child 프로세스를 기다림.

    if (pid == -1) {
        fprintf(stderr, "wait error: %s\n", strerror(errno));
    } else {
        if (WIFEXITED(status)) {
            printf("프로그램에서 exited(%d) 또는 main에서 return %d;하여 종료되었습니다.\n", 
                                                WEXITSTATUS(status));
        } else if (WIFSIGNALED(status)) {
            printf("signal %d번이 발생하여 종료되었습니다.\n", WTERMSIG(status));
        } else if (WIFSTOPPED(status)) {
            printf("signal %d번으로 인하여 stop되었습니다.\n", WSTOPSIG(status));
        } else if (WIFCONTINUED(status)) {
            printf("STOP된 프로세스를 진행합니다.\n");
        }
    }
    
    return 0;
}

 

 


see also: Process 관리 함수 

 

 

 

블로그 이미지

사용자 자연&사람

행복한 개발자 programmer since 1995.

댓글을 달아 주세요