wait

等待子进程中断或者结束

头文件

#include < sys/wait.h >

函数原型

pid_t wait(int *status)

函数说明

wait()会暂时停止目前进程的执行,直到有信号来到或子进程结束。如果在调用wait()时子进程已经结束,则wait()会立即返回子进程结束状态值。子进程的结束状态值会由参数status 返回,而子进程的进程识别码也会一块返回。如果不在意结束状态值,则status可以设成NULL。

status中某些位定义了退出状态(正常返回), 其他位则指示信号编号(异常返回),有一位指示是否产生了core文件

关于status的说明:

  • 正常终止
    进程终止状态 = 终止原因(正常终止) << 8 | 退出状态的低8位
  • 异常终止
    进程终止状态 = 是否产生core文件位|终止原因(异常终止) << 8 | 终止该进程的信号

OS 处理终止状态的带参宏:

  • WEXITSTATUS(status) 获取正常终止时子进程传送给exit或者_exit参数的低8位
  • WTERMSIG(status) 异常终止时,获取子进程终止的信号编号
  • WSTOPSIG(status) 暂停状态时,获取子进程暂停的信号编号
  • WIFEXITED(status) 正常终止子进程返回的状态
  • WIFSIGNALED(status) 异常终止子进程返回的状态
  • WIFSTOPPED(status) 暂停子进程的返回状态
  • WIFCONTINUED(status) 作业控制暂停后已经继续的子进程返回的状态

返回值

如果执行成功则返回子进程识别码(PID),如果有错误发生则返回-1。失败原因存于errno中。

错误码

ECHILD 没有可等待的子进程
EINTR 对于waitpid而言WNOHANG 没有设置且一个非阻塞的信号或者SIGCHLD信号捕获
EINVAL 参数错误

范例

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

void pr_exit(int);

int main(int argc, char *const argv[]) {

    pid_t pid;

    int status;

    if (fork() == 0){
        printf("this is the child process, pid=%d\n", getpid());
        sleep(30);
        _exit(10);
    } else {
        //sleep(1);
        printf("this is the parent process, wait for child...\n");
        pid = wait(&status);
        printf("child's pid=%d\n", pid);
        pr_exit(status);
    }
    return 0;
}

void pr_exit(int status) {
    if (WIFEXITED(status)) {
        printf("normal termination, exit status = %d\n", WEXITSTATUS(status));
    } else if(WIFSIGNALED(status)) {
        printf("abnormal termination, signal number = %d%s\n", 
        WTERMSIG(status),
#ifdef WCOREDUMP
        WCOREDUMP(status) ? "core file generated" : "");
#else 
        "");
#endif
    } else if(WIFSTOPPED(status)) {
        printf("child stopped, signal number i= %d\n", WSTOPSIG(status));
    }
}

执行

  1. 正常结束

    [root@iz2zecj7a5r32f2axsctb9z process]# ./wait
    this is the parent process, wait for child...
    this is the child process, pid=2839
    child's pid=2839
    normal termination, exit status = 10
  2. 给子进程发送SIGKILL信号

    [root@iz2zecj7a5r32f2axsctb9z process]# ./wait
    this is the parent process, wait for child...
    this is the child process, pid=3022
    child's pid=3022
    abnormal termination, signal number = 9
  3. 给子进程发送SIGABRT信号

    [root@iz2zecj7a5r32f2axsctb9z process]# ./wait
    this is the parent process, wait for child...
    this is the child process, pid=3530
    child's pid=3530
    abnormal termination, signal number = 6
  4. 给子进程发送SIGALRM信号

    [root@iz2zecj7a5r32f2axsctb9z process]# ./wait
    this is the parent process, wait for child...
    this is the child process, pid=3570
    child's pid=3570
    abnormal termination, signal number = 14

如果没有子进程 调用wait则报ECHILD错误

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

int  main(int argc, char *argv[]) {
    pid_t pid;
    printf("process\n");
    pid = wait(NULL);
    if(pid < 0) {
        perror("wait");
        return -1;
    }
    return 0;
}

执行结果:

[root@iz2zecj7a5r32f2axsctb9z process]# ./nowait 
process
wait: No child processes
文档更新时间: 2021-03-05 22:31   作者:周国强