C언어 자식 프로세스 종료 확인 함수 waitpid ()

2020. 3. 15. 11:46 컴퓨터/프로그래밍

C함수 자식 프로세스 종료 확인 waitpid()

wait()함수처럼 자식 프로세스가 종료될 때까지 대기합니다. 차이점은 wait() 함수가 자식 프로세스 중 어느 하나라도 종료되면 복귀되지만, 즉 대기에서 풀리지만 waitpid()는 특정 자식 프로세스가 종료될 때까지 대기 합니다.

또한, wait()는 자식 프로세스가 종료될 때까지 block되지만 waitpid()는 WNOHANG 옵션을 사용하면 block되지 않고 다른 작업을 진행할 수 있습니다.

  • 헤더: wait.h
  • 형태: pid_t waitpid(pid_t pid, int *status, int options)
  • 인수: pid_t pid 감시할 자식 프로세스 ID
    int *status 자식 프로세스의 종료 상태 정보
    int options 대기를 위한 옵션
  • 반환: int 정상: 종료된 자식 프로세스 ID
    실패: -1, WNOHANG를 사용했고 자식 프로세스가 종료되지 않았다면: 0
reference

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

첫번째 인수 pid_t pid는 감시 대상인 자식 프로세스의 ID입니다. 이 ID값에는 자식 프로세스 ID외에도 아래와 같은 값을 지정할 수 있습니다.

pid 설명
-1 여러 자식 중 하나라도 종료되면 복귀, wait()와 같은 처리
0 현재의 프로세스의 그룹 ID와 같은 그룹의 자식 프로세스가 종료되면 복귀
양수 pid에 해당하는 자식 프로세스가 종료되면 복귀

3번재 인수 options는 여러 상수 값이 있습니다만 WNOHANG와 0을 많이 사용합니다.

options 설명
WNOHANG 자식 프로세스가 종료되었는지 실행 중인지만 확인하고 바로 보귀. 즉, 부모프로세스는 bock되지 않음
0 자식 프로세스가 종료될 때까지 block됨. 즉, wait()와 같은 처리

WNOHANG를 사용했을 경우 waitpid()는 자식 프로세스의 종료 상태를 확인하고 바로 복귀합니다. 만일 자식 프로세스가 활동 중이라면 0을 반환하고, 종료되면 자식 프로세스의 ID가 반환됩니다.

예제 1

#include <stdio.h>
#include <unistd.h>
#include <wait.h>

int main()
{
   int   counter  = 1;
   int   status;
   pid_t pid;
   pid_t pid_child;
       
   printf( "부모: 첫번째 자식 프로세스를 생성합니다.\n");    
   pid   = fork();

   switch( pid){
   case -1  :
      printf( "자식 프로세스 생성 실패\n");
      return -1;
   case 0   :
      printf( "1st: 저는 첫번째 자식 프로세스로 5까지 카운트하고 종료하겠습니다.\n");
      while( 6 > counter ){
         printf( "1st: %d\n", counter++);
         sleep( 1);
      }
      return 99;
   default  :
      printf( "부모: 두번째 자식 프로세스를 생성합니다.\n");    
      pid   = fork();
   
      switch( pid){
      case -1  :
         printf( "자식 프로세스 생성 실패\n");
         return -1;
      case 0   :
         printf( "2nd: 저는 두번째 자식 프로세스로 10까지 카운트하고 종료하겠습니다.\n");
         while( 11 > counter ){
            printf( "2nd: %d\n", counter++);
            sleep( 1);
         }
         return 99;
      default  :
         printf( "부모: 저는 부모 프로세스로 자식 프로세스 작업이 \
끝날 때 까지 대기합니다..\n");
   
         pid_child   = waitpid( pid, &status, 0);
   
         printf( "부모: 종료된 자식 프로세스 ID는 %d이며,", pid_child);
         if ( 0 == ( status & 0xff)){
            printf( "정상적으로 종료되었고 반환값은 %d입니다\n", status >> 8);
         } else {
            printf( "비 정상으로 종료되었고 종료 시그널 번호는 %d입니다\n", status);
         }
         printf( "이제 제일을 처리하겠습니다.\n");
         while( 1 ){
            printf( "부모: %d\n", counter++);
            sleep( 1);
         }
      }
   }
}

실행 결과

]$ ./a.out
부모: 첫번째 자식 프로세스를 생성합니다.
부모: 두번째 자식 프로세스를 생성합니다.
부모: 저는 부모 프로세스로 자식 프로세스 작업이 끝날 때 까지 대기합니다..
2nd: 저는 두번째 자식 프로세스로 10까지 카운트하고 종료하겠습니다.
1st: 저는 첫번째 자식 프로세스로 5까지 카운트하고 종료하겠습니다.
2nd: 1
1st: 1
2nd: 2
1st: 2
1st: 3
2nd: 3
1st: 4
2nd: 4
1st: 5
2nd: 5
2nd: 6
2nd: 7
2nd: 8
2nd: 9
2nd: 10
^C
]$

예제 2 WNOHANG 옵션을 사용

이번 예제는 WNOHANG 옵션을 사용하여 부모 프로세스가 block되지 않고 자식 프로세스의 종료 상태를 확인하는 예제입니다.

#include <stdio.h>
#include <unistd.h>
#include <wait.h>

int main()
{
   int   counter  = 1;
   int   status;
   pid_t pid;
   pid_t pid_child;

   printf( "부모: 첫번째 자식 프로세스를 생성합니다.\n");
   pid   = fork();

   switch( pid){
   case -1  :
      printf( "자식 프로세스 생성 실패\n");
      return -1;
   case 0   :
      printf( "1st: 저는 첫번째 자식 프로세스로 5까지 카운트하고 종료하겠습니다.\n");
      while( 6 > counter ){
         printf( "1st: %d\n", counter++);
         sleep( 1);
      }
      return 99;
   default  :
      printf( "부모: 두번째 자식 프로세스를 생성합니다.\n");
      pid   = fork();

      switch( pid){
      case -1  :
         printf( "자식 프로세스 생성 실패\n");
         return -1;
      case 0   :
         printf( "2nd: 저는 두번째 자식 프로세스로 10까지 카운트하고 종료하겠습니다.\n");
         while( 11 > counter ){
            printf( "2nd: %d\n", counter++);
            sleep( 1);
         }
         return 99;
      default  :
         printf( "부모: 저는 부모 프로세스로 자식 프로세스 작업이 \
종료되었는지 확인하면서 제일을 하겠습니다.\n");

         while( 1 ){
            printf( "부모: %d\n", counter++);
            pid_child   = waitpid( pid, &status, WNOHANG);
            if ( 0 != pid_child){
               printf( "자식 프로세스가 종료되었습니다.\n");
            }
            sleep( 1);
         }
      }
   }
}

실행 결과

]$ ./a.out
부모: 첫번째 자식 프로세스를 생성합니다.
부모: 두번째 자식 프로세스를 생성합니다.
1st: 저는 첫번째 자식 프로세스로 5까지 카운트하고 종료하겠습니다.
부모: 저는 부모 프로세스로 자식 프로세스 작업이 종료되었는지 확인하면서 제일을 하겠습니다.
부모: 1
1st: 1
2nd: 저는 두번째 자식 프로세스로 10까지 카운트하고 종료하겠습니다.
2nd: 1
1st: 2
2nd: 2
부모: 2
2nd: 3
1st: 3
부모: 3
1st: 4
2nd: 4
부모: 4
2nd: 5
부모: 5
1st: 5
2nd: 6
부모: 6
2nd: 7
부모: 7
2nd: 8
부모: 8
부모: 9
2nd: 9
^C
]$
이 댓글을 비밀 댓글로
  1. 잘보고 공감하고 갑니다