반응형

 waitpid_wait

# waitpid와 wait : 자식 프로세스의 종료

  waitpid와 wait은 일반적으로 생성된 자식 프로세스가 종료하거나 멈추도록 기다리거나, 그러한 상황인지를 판단하는데 사용할 수 있는 함수들이다. 우선 waitpid의

함수 원형은 다음과 같다.


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


  waitpid 함수는 프로세스 ID가 pid인 프로세스의 상태정보를 얻어오는데 주로 사용된다. 각각의 인수들은 이름을 보면 어떠한 것을 의미하는지 대략 짐작 가능할 것이

다.

  - pid : 상태를 알아보고자 하는 프로세스의 ID이다. -1 이나 WAIT_ANY로 설정하면 어떤 자식 프로세스든 하나만 종료하기를 기다리겠다는것을 뜻하고(즉, wait 함수

와 같은 방식으로 동작하게 된다), 0 이나 WAIT_MYPGRP는 호출된 프로세스와 같은 그룹에 있는 어떤 자식프로세스든 하나만 종료하기를 기다리겠다는것을 뜻한다. 그리

고 음수값이라면 그 절대값의 그룹 ID 내의 자식 프로세스를 위한 정보를 요청하게 된다.

  - options : 비트마스크이다. 0과 다음 두 값들의 OR로 구성한다.
    WNOHANG : 어떤 자식이 종료되지 않았더라도 함수는 바로 리턴된다.
    WUNTRACED : 종료된 프로세스 뿐만 아니라 멈춘 프로세스로부터도 상태정보를 얻어온다.

  - status : 프로세스의 상태를 얻어오는데 필요하다. NULL이 아니라면 여기에 프로세스의 상태가 저장이 되는데 다음의 매크로들로 알 수 있다.
    WIFEXITED( status ) : 정상적으로 종료되었다면 non-zero이다.
    WEXITSTATUS( status ) : return 값이 설정되고 종료된 프로세스 리턴값의 최하 8비트를 평가한다.
    WIFSIGNALED( status ) : 자식 프로세스가 어떤 시그널에 의해 종료되었다면 TRUE 값을 반환한다.
    WTERMSIG( status ) : 자식 프로세스가 시그널에 의해 종료된 경우, 시그널 번호를 반환한다.
    WIFSTOPPED( status ) : 자식 프로세스가 현재 정지된 상태라면 TRUE를 반환한다.
    WSTOPSIG( status ) : 자식 프로세스가 정지된 상태가 되도록 한 시그널 번호를 반환한다.

  리턴값은 에러라면 -1, WNOHANG이 사용되고 어떤 자식도 이용되지 않았다면 0, 그 이외의 정상적인 경우는 보고된 상황을 가진 자식 프로세스의 PID이다.

  에러가 발생했을 때 errno 값은 다음과 같은 것들이 있다.
  - EINTR : 시그널에 의해 인터럽트 됨
  - ECHILD : pid로 지정된 프로세스가 존재하지 않거나 호출한 프로세스의 자식이 아님
  - EINVAL : options 값이 유효하지 않음
  - ERESTARTSYS : WNHANG이 설정되지 않았는데 시그널이 잡혔을 때
  - ENOBUFS : 버퍼가 부족할 때

wait 함수는 앞에서 이미 언급했다시피 waitpid의 pid_t 인자가 -1일때와 동일하게 동작한다. wait(&status)는 waitpid(-1, &status, 0)와 완전히 동일하다.

다음은 waitpid의 사용예이다. 기다림이 없이, 종료된 모든 자식 프로세스에게서 보내온 그들의 상태를 얻는다.


void sigchild_handler( int signum ) {

  pid_t pid;
  int   status;
  int   child_val;

  /*** 특정OS에서는 세팅을 해줘야처리가 됨. Set up handler again. ***/
  /*** (void) signal( SIGCHLD, sigchild_handler ); ***/

  while(1) {

    pid = waitpid( -1, &status, WNOHANG );

    if( pid == 0 ) {   /* none left */

        break;

    }

    if ( pid < 0 ) {

        /*
  * calling standard I/O functions like fprintf() in a signal handler is not recommended, but probably OK in simple programs like this one.
 */

        if ( errno == EINTR || errno == EAGAIN ) {

            continue;

        }

        /* ECHILD shouldn't happen with the WNOHANG option, but with some kernels it does anyway.  Ignore it. */
       
        if ( errno != ECHILD )
        {  
            fprintf(stdout,  "child waitpid errno[%d][%s]", errno, strerror(errno) ); fflush(stdout);
        }
       
        break;

    }

    /*
     * We now have the info in 'status' and can manipulate it using the macros in wait.h
     */

    if (WIFEXITED(status))                /* did child exit normally? */
    {
        child_val = WEXITSTATUS(status);  /* get child's exit status */
 fprintf(stderr, "child's exited normally with status %d\n", child_val);
    }

  }

}


  waitpid와 wait은 sys/wait.h에 있다.


반응형
Posted by 공간사랑
,