博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
waitpid()设置WNOHANG位(非阻塞模式)判断子进程的状态是否有所改变
阅读量:5342 次
发布时间:2019-06-15

本文共 1720 字,大约阅读时间需要 5 分钟。

参考《Linux/Unix系统编程手册》26.1.5,对于系统调用waitid()

#include 
int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);

若在option中设置WNOHANG位,与那么该系统调用就是非阻塞的,也就是说会立刻返回而不是等待子进程的状态发生变化。

如果子进程的状态(正在运行or正常退出or被信号终止or被信号停止)发生变化,则会把状态具体信息保存在类型为siginfo_t结构的变量中。

PS:在sigaction处理信号时,也可以选用这个结构。

书上特意强调了一种情况,那就是,对于这种非阻塞操作假如子进程状态并未发生变化(也就是说正在运行,阻塞状态也可以算作未发生变化),infop指向的结构信息不会发生任何变化,因此需要预先memset将infop指向的结构每一位置为0,如果调用waitid()之后仍为0,则代表子进程状态未发生变化(简单来讲可理解为未退出)。

siginfo_t info;// TODO:设置好waitid()的几个参数idtype、id、options// ...memset(&info, 0, sizeof(siginfo_t));if (waitid(idtype, id, &info, options | WNOHANG) == -1)    // TODO: 错误处理    exit(1);if (info.si_pid == 0) {    // 子进程状态未发生改变} else {    // 子进程状态发生改变,状态信息存储到了info中}

然后我就想到了,如果是使用waitpid()呢?

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

waitpid()仅仅将状态保存在int变量status中,书上很多代码是像这样

int status;if (waitpid(pid, &status, options) == -1) {    // TODO: 错误处理    exit(1);}

这有个问题,就是status并没有进行初始化,以前写C++的时候,记住的一条准则就是别忘记给变量赋初值。但是发现在很多C代码中都没有这个行为,之前在哪里看过这有利于检查错误,因为往往未赋初值的变量会导致错误,于是一直就这么写下来了。

于是我在写了份测试代码:调用fork()创建进程,子进程休眠1秒就_exit(1)退出,父进程则立刻调用waitpid(childPid, &status, WNOHANG);

理论上父进程的waitpid返回0(调用成功),因为childPid是对的,但是status状态千奇百怪,后来发现原因就是:子进程状态未发生改变时,status的值不变,于是status就是系统默认初始值(并未确定)。

按照waitid()的思路,就是给status一个初值,然后检查调用waitpid()调用后status的值是否发生了变化。

问题就来了,status该设为什么值呢?

其实这里设为-1就行了。

那么有人会问,如果_exit(-1);退出呢?

退出码是个1字节的整型,而int至少占2个字节,也就是初始状态为11111111 11111111

而如果waitpid()得到的status为-1,其实是1个字节,转换成2个字节int后就是11111111 00000000(小端模式下),和原来的-1有所不同。

实验结果也证明了这点

第1个结果是子进程阻塞,status不变,因此状态status为最初的-1,未知

第2个结果是父进程先阻塞再调用waitpid(),此时子进程已经_exit(-1)退出了,状态status经过WEXITSTATUS转换后是255,即(unsigned char)-1。

转载于:https://www.cnblogs.com/Harley-Quinn/p/7157579.html

你可能感兴趣的文章
[nodejs]Buffer vs String
查看>>
python 数值计算库
查看>>
java 服务重启 js 中被注释代码仍然执行
查看>>
我并不是不闻不问![C#]
查看>>
全站仪数据修正为南方cass可识别数据
查看>>
插件大全网址
查看>>
2016/4/2 json:js和jquery中轻量级数据交换格式 例: 窗口弹出 popwindow
查看>>
ABAP EXCEL数据上传时因为栏位字符串过长而被截断的问题解决方法
查看>>
CF1076E Vasya and a Tree
查看>>
Linux 的基本操作(文件与目录管理)
查看>>
LeetCode 9. Palindrome Number
查看>>
python——排序
查看>>
同时使用Binding&StringFormat 显示Text【项目】
查看>>
过拟合与欠拟合 之原因和解决方法
查看>>
线段树+差分【p1438】无聊的数列
查看>>
如何修炼成某一领域的高手?
查看>>
关于deepin上谷歌浏览器会出现延时的问题
查看>>
Mobility Express部署外部镜像服务器
查看>>
关于Mobility Express转LAP注意事项
查看>>
web前端经典小题
查看>>