wait和waitpid

本文介绍了 Linux/Unix 系统编程中 wait 和 waitpid 两个系统调用的作用与区别,帮助读者理解它们在子进程终止后如何回收资源、避免僵尸进程的产生。
single

函数介绍

我们可以通过 fork 函数来创建子进程。创建子进程后,父进程具有监听子进程的运行状态的能力,用到的函数为:

#include <sys/wait.h>
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);

进程一旦调用了 wait,就立即阻塞自己,由 wait 自动分析是否当前进程的某个子进程已经退出:

  • 如果让它找到了这样一个已经变成僵尸的子进程,wait 就会收集这个子进程的信息,并把它彻底销毁后返回
  • 如果没有找到这样一个子进程,wait 就会一直阻塞在这里,直到有一个出现为止。

参数: status 用来保存被收集进程退出时的一些状态,它是一个指向 int 类型的指针。但如果我们对这个子进程是如何死掉的毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可以设定这个参数为 NULL。

返回值:

  • 如果成功,wait 会返回被收集的子进程的进程 ID;
  • 如果调用进程没有子进程,调用就会失败,此时 wait 返回-1,同时 errno 被置为 ECHILD

以上函数用于等待子进程的状态变化回调并且获取状态变化信息。 所能获取到的状态变化包括:子进程运行结束、子进程被信号量暂停、子进程被信号量恢复运行。

wait和waitpid区别

waitwaitpid 的区别:

  • wait 会令调用者阻塞直到某个子进程终止;
  • waitpid 则可以通过设置一个选项来设置为非阻塞,另外 waitpid 并不是等待第一个结束的进程而是等待参数中 pid 指定的进程。

waitpid不同参数的不同效果

pid 不同值作用不同:

  • pid=-1 等待任意子进程,此种情况下,waitpid 与 wait 等效;
  • pid>0 等待进程 ID 与 pid 相等的子进程;
  • pid>=0 等待组 ID 等于调用进程组 ID 的任一子进程;
  • pid<-1 等待组 ID 等于 pid 绝对值的任一子进程。

options 参数:

  • WNOHANG 如果 pid 指定的子进程没有结束,则 waitpid() 函数立即返回0,而不是阻塞在这个函数上等待;如果结束了,则返回该子进程的进程号;
  • WUNTRACED 如果子进程进入暂停状态,则马上返回。