0%

waitpid

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

man 2 waipid

int status;
child_pid = fork();
if (child_pid == 0) {
    // in child; do stuff including perhaps exec
} else if (child_pid == -1) {
    // failed to fork 
} else {
    if (waitpid(child_pid, &status, WNOHANG) == child_pid) {
        // child exited or interrupted; now you can do something with status
    } else {
        // error etc
    }
}

WNOHANG return immediately if no child has exited.

其中 status 存储的是子进程中 exit code,常用一下宏来判断使用 status

  • WIFEXITED(wstatus),程序调用exit 或者 _exit 正常退出
  • WEXITSTATUS(wstatus),当WIFEXITED返回TRUE时,用于获取 exit code
  • WIFSIGNALED(wstatus),程序由信号中止
  • WTERMSIG(wstatus),当WIFSIGNALED返回TRUE时,获取信号值
  • WCOREDUMP(wstatus),returns true if the child produced a core dump.
  • WIFSTOPPED(wstatus),returns true if the child process was stopped by delivery of a signal
  • WSTOPSIG(wstatus),returns the number of the signal which caused the child to stop.
  • WIFCONTINUED(wstatus),returns true if the child process was resumed by delivery of SIGCONT.

example

pid = fork();
if(pid < 0)
{
    printf("fork failed\n");
    return -1;
}
else if(pid == 0)
{
    sleep(5);
    printf("Child process\n");
    return 2;
}
else
{
    printf("Parent process\n");
    kill(pid, SIGKILL);
    waitpid(pid, &ret, 0);
    if(WIFEXITED(ret))
        printf("Child process returned normally\n");
    if(WIFSIGNALED(ret))
        printf("Child process terminated by signal\n");
    return 1;
}
int status = 0;
if(waitpid(pid, &status, WNOHANG) == 0) {
    //do something
}
else {
    if(WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM) {
        //signal SIGTERM caused the child process to terminate
    }
}