一、前言

首先在了解waitpid()函数之前,我们需要先明确以下几个概念。

1.进程状态

从程序员的角度,我们可以认为进程总是处于下面三种状态之一:

(1)运行。进程要么在CPU上执行,要么在等待被执行且最终会被内核调度。

(2)停止。进程的执行被挂起(suspended),且不会被调度。当收到SIGSTOP、SIGTSTP、SIGTTIN或者SIGTTOU信号时,进程就停止,并且保持停止直到他收到一个SIGCONT信号,在这个时刻,进程再次开始运行。

(3)终止。进程永远的停止了。进程会因为三种原因终止:第一、收到一个信号,信号的默认行为是终止进程。第二、从主程序返回。第三、调用exit函数

2.回收子进程

当一个进程由于某种原因终止时,内核并不是立即把它从系统中清除 。相反,进程被保持在一种已终止的状态中,直到被它的父进程回收(reaped)。 当父进程回收已终止的子进程时,内核将子进程的退出状态传递给父进程,然后抛弃已终止的进程,从此时开始,该进程就不存在了 。一个终止了但还未被回收的进程称为僵死进程 (zombie)。如果一个进程在回收他的子进程之前就终止了,那他的子进程被称为孤儿进程。

如果一个父进程终止了,内核会安排 init 进程成为它的孤儿进程的养父。init进程的 PID 为 1, 是在系统启动时由内核创建的 ,它不会终止 ,是所有进程的祖先 。如果父进程没有回收它的僵死子进程就终止了,那么内核会安排 init 进程去回收它们 。不过,长时间运行的程序,比如 shell 或者服务器,总是应该回收它们的僵死子进程 。即使僵死子进程没有运行,它们仍然消耗系统的内存资源。
        一个进程可以通过调用 waitpid 函数来等待它的子进程终止或者停止。

二、waitpid()函数详解

pid_t waitpid (pid_t pid, int* statusp, int options);
返回 :如果成功,则为子进程的PID,如果options为WNOHANG,则返回0,如果发生其他错误,则返回-1。

waitpid函数有点复杂 。默认情况下 (当 options=0 时 ),waitpid挂起调用进程的执行,直到它的等待集合 (wait set) 中的一个子进程终止。如果等待集合中的一个进程在刚调用的时刻就已经 终止了,那么 waitpid 就立即返回 。在这两种情况中,waitpid返回导致 waitpid 返回的已终止子进程的PID此时,已终止的子进程已经被回收,内核会从系统中删除掉它的所有痕迹。
1. 判定等待集合的成员
        等待集合的成员是由参数 pid 来确定的:

(1)如果Pid>0,那么等待集合就是一个单独的子进程 ,它的进程 ID 等于 pid。
(2)如果Pid=-1,那么等待集合就是由父进程所有的子进程组成的。
2. 修改默认行为
        可以通过将 options 设置为常量 WNOHANG、WUNTRACED 和 WCONTINUED
的各种组合来修改默认行为:
WNOHANG: 如果等待集合中的任何子进程都还没有终止,那么就立即返回(返回值为0)。 默认的行为是挂起调用进程,直到有子进程终止 。在等待子进程终止的同时,如果还想做些有用的工作,这个选项会有用。
WUNTRACED: 挂起调用进程的执行,直到等待集合中的一个进程变成已终止或者被停止 。返回的PID 为导致返回的已终止或被停止子进程的 PID。默认的行为是只返回已终止的子进程。当你想要检査已终止和被停止的子进程时,这个选项会有用。
WCONTINUED: 挂起调用进程的执行,直到等待集合中一个正在运行的进程终止或等待集合中一 个被停止的进程收到 SIGCONT 信号重新开始执行。
        可以用或运算把这些选项组合起来 。例如:WNOHANG | WUNTRACED: 立即返回,如果等待集合中的子进程都没有被停止或终止,则返回值为0: 如果有一个停止或终止,则返回值为该子进程的 PID。
3. 检查已回收子进程的退出状态
        如果statusp参数是非空的,那么waitpid就会在 status 中放上关于导致返回的子进程的状态信息, status是statusp指向的值。 wait.h头文件定义了解释status参数的几个宏:
WIFEXITED(status):如果子进程通过调用 exit 或者一个返回 (return) 正常终止,就返回真。
WEXITSTATUS(status):返回一个正常终止的子进程的退出状态。只有在WIFEXITED()返回为真时,才会定义这个状态。
WIFSIGNALED(status):如果子进程是因为一个未被捕获的信号终止的,那么就返回真。
WTERMSIG(status):返回导致子进程终止的信号的编号 。只有在 WIFSIGNALED()返回为真时,才定义这个状态。
WIFSTOPPED(status):如果引起返回的子进程当前是停止的,那么就返回真。
WSTOPSIG(status):返回引起子进程停止的信号的编号。只有在 WIFSTOPPED()返回为真时,才定义这个状态。
WIFCONTINUED(status):如果子进程收到SIGCONT信号重新启动,则返回真。
4. 错误条件
        如果调用进程没有子进程,那么waitpid返回-1, 并且设置 errno为ECHILD。 如果waitpid函数被一个信号中断,那么它返回-1,并设置errno为EINTR。

注意,程序不会按照特定的顺序回收子进程。子进程回收的顺序是这台特定的计算机系统的属性 。在另一个系统上,甚至在同一个系统上再执行一次,两个子进程都可能以相反的顺序被回收。这是非确定性行为的一个示例,这种非确定性行为使得对并发进行推理非常困难。两种可能的 结果都同样是正确的,作为一个程序员,我们绝不可以假设总是会出现某一个结果,无论多么不可能出现另一个结果 。唯一正确的假设是每一个可能的结果都同样可能出现。

waitpid()函数详解相关推荐

  1. waitpid函数详解+应用示例

    来源:微信公众号「编程学习基地」 文章目录 waitpid函数的使用 waitpid()函数定义 参数详解 使用示例 waitpid函数的使用 当用fork启动一个新的子进程的时候,子进程就有了新的生 ...

  2. Linux系统编程之waitpid函数详解

    5.1 为什么要进行进程资源的回收 当一个子进程退出之后,该进程能够回收自己的用户区的资源,但是不能回收内核空间区的PCB(process control block 进程控制块)资源. (即:子进程 ...

  3. wait()函数和waitpid()函数详解

    文章目录 1. wait()函数 2. waitpid()函数 3. wait() 和 waitpid() 用法和比较 1. wait()函数 #include <sys/types.h> ...

  4. linux下wait函数,Linux wait函数详解

    wait和waitpid出现的原因 SIGCHLD --当子进程退出的时候,内核会向父进程SIGCHLD信号,子进程的退出是个异步事件(子进程可以在父进程运行的任何时刻终止) --子进程退出时,内核将 ...

  5. C语言网络编程:accept函数详解

    文章目录 前言 函数描述 代码实例 如何得到客户端的IP 和 端口号 前言 当使用tcp服务器使用socket创建通信文件描述符,bind绑定了文件描述符,服务器ip和端口号,listen将服务器端的 ...

  6. 【FFmpeg】函数详解(三)

    FFmpeg函数详解 14.av_write_frame 15.av_interleaved_write_frame 16.av_write_trailer 17.avio_close 18.av_i ...

  7. 【FFmpeg】函数详解(二)

    FFmpeg函数详解 9.av_dump_format 10.avio_open 11.avformat_write_header 12.avcodec_send_frame 13.avcodec_r ...

  8. 【FFmpeg】函数详解(一)

    FFmpeg函数详解 一.错误码相关 1.AVERROR 2.av_strerror 3.其他错误码解释 二.编解码 1.获取编解码器 2.申请.释放上下文环境 3.打开编码器avcodec_open ...

  9. 【ES6】Generator函数详解

    [ES6]Generator函数详解 一.Generator函数简介 基本概念 函数写法 yield关键字介绍 二.next方法的参数 三.for...of循环 四.关于普通throw()与Gener ...

最新文章

  1. 3D视觉创新应用(三维重建)竞赛作品系列——人体三维精准量测与动作捕捉
  2. 《研磨设计模式》chap8 生成器模式Builder
  3. 2017c 语言程序设计,C语言程序设计第一次作业(2017.10.10完成)
  4. OpenCV使用VideoCapture界面读取一系列图像的实例(附完整代码)
  5. matlab考试题烟台大学,徐骞-计算机控制与工程学院
  6. Vijos P1127 级数求和【数列】
  7. 扫雷源代码(C语言)
  8. [技巧] 论文自动更新参考文献序号
  9. Logistic(逻辑)回归分析
  10. 计算机网络与通信第二版复习,自学考试计算机网络与通信笔记第二章
  11. chromebook安装devos和chrome os双启动经验分享
  12. 使有用计算机不注意卫生,“十种举措”,远离干眼
  13. android solid代码,Android中形状图形 | shape图形常用的3个节点:corners(圆角)、solid(填充) 和 stroke(描边)...
  14. Cocos2dx 3.2移植到Android 完全可行的方法
  15. mysql 有没有minus_MySQL实现差集(Minus)和交集(Intersect)
  16. 为什么要隐藏ip地址
  17. 网络基础(二)之HTTP与HTTPS
  18. AboutSpace
  19. 【转】模仿绘画风格的算法:A Neural Algorithm of Artistic Style
  20. 大创项目:少儿编程直播平台

热门文章

  1. Java岗位面试题(南京才丰软件技术开发有限公司)
  2. Apache Dolphinscheduler3.0.0-beta-1 版本发布,新增FlinkSQL、Zeppelin任务类型
  3. ES系列知识补充与应用实践
  4. 如何发包到npmjs上
  5. printf函数 + scanf函数
  6. 低成本高安全的华为数据库
  7. WSockExpert0.6 beta 1工具介绍和使用实例
  8. dr.oracle素颜霜好用吗,经常用素颜霜对皮肤有危害吗 怎么涂比较好
  9. iOS绘图——Quartz 2D使用方法
  10. chrome android 2.3,【安卓2.3谷歌框架单刷包】安卓2.3谷歌GMS服务框架