waitpid()设置WNOHANG位(非阻塞模式)判断子进程的状态是否有所改变
参考《Linux/Unix系统编程手册》26.1.5,对于系统调用waitid()
#include <sys/wait.h> 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 <sys/wait.h> 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。
waitpid()设置WNOHANG位(非阻塞模式)判断子进程的状态是否有所改变的更多相关文章
- UDP socket 设置为的非阻塞模式
UDP socket 设置为的非阻塞模式 Len = recvfrom(SocketFD, szRecvBuf, sizeof(szRecvBuf), MSG_DONTWAIT, (struct so ...
- 服务器编程心得(四)—— 如何将socket设置为非阻塞模式
1. windows平台上无论利用socket()函数还是WSASocket()函数创建的socket都是阻塞模式的: SOCKET WSAAPI socket( _In_ int af, _In_ ...
- 看到关于socket非阻塞模式设置方式记录一下。
关于socket的阻塞与非阻塞模式以及它们之间的优缺点,这已经没什么可言的:我打个很简单的比方,如果你调用socket send函数时: 如果是阻塞模式下: send先比较待发送数据的长度len和套接 ...
- 非阻塞模式ServerSocketChannel 聊天室服务器端
import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import ja ...
- socket异步通信-如何设置成非阻塞模式、非阻塞模式下判断connect成功(失败)、判断recv/recvfrom成功(失败)、判断send/sendto
socket异步通信-如何设置成非阻塞模式.非阻塞模式下判断connect成功(失败).判断recv/recvfrom成功(失败).判断send/sendto 博客分类: Linux Socket s ...
- 使用命名管道的OVERLAPPED方式实现非阻塞模式编程 .
命令管道是进程间通讯的一种常用方式,对于命令管道的介绍可以参考别的资料和书籍,这里推荐一个<VC++下命名管道编程的原理及实现>这篇博文,写得比较清楚.但是都是介绍了阻塞模式的编程,我这里 ...
- linux-socket connect阻塞和非阻塞模式 示例
~/cpp$ ./connect 192.168.1.234 1234 kkkk block mode: ubuntu 14.04 : time used:21.0.001053s connect ...
- PHP非阻塞模式 (转自 尘缘)
让PHP不再阻塞当PHP作为后端处理需要完成一些长时间处理,为了快速响应页面请求,不作结果返回判断的情况下,可以有如下措施: 一.若你使用的是FastCGI模式,使用fastcgi_finish_re ...
- Socket 阻塞模式和非阻塞模式
阻塞I/O模型: 简介:进程会一直阻塞,直到数据拷贝 完成 应用程序调用一个IO函数,导致应用程序阻塞,等待数据准备好. 如果数据没有准备好,一直等待….数据准备好了,从内核拷贝到用户空间,IO函数返 ...
随机推荐
- 自定义URL协议在Web中启动本地应用程序
转自(http://blog.csdn.net/jackychen_king/article/details/7743811) 1.注册应用程序来处理自定义协议 你必须添加一个新的key以及相关的va ...
- MySQL简单的操作,增删改查
B/S架构模式与C/S架构模式的区别 B/S=WEB/SERVER C/S=CLIENT/SERVIR B/S:用户通过web浏览器打开域名就能访问服务器server的方式就叫做B/S用户不需要安装任 ...
- 最大匹配算法 (Maximum Matching)
之所以研究这个算法,是因为最近在研究NLP中文的分词,所谓分词就是将一个完整的句子,例如“计算语言学课程有意思”,分解成一些词组单元“计算语言学,课程,有,意思”. “最大匹配法” 在中文分词中有所应 ...
- 【Html 学习笔记】第四节——框架
我们经常使用的网页可能不是一个单独的网页,而是多个嵌套的,那么就需要用到下面的技术. 垂直框架:<frameset cols=""> 这里需要注意的是:四个网页需要同时 ...
- jquery中ajax跨域的写法
由于JS同源策略的影响,因此js只能访问同域名下的文档.因此要实现跨域,一般有以下几个方法: 一.处理跨域的方式: 1.代理 2.XHR2 HTML5中提供的XMLHTTPREQUEST Level2 ...
- 【前端工具】 在 Windows 下安装 GruntJS——教程(译)
在你安装 Grunt.js 之前你需要先安装 Node.js.对于本教程而言,我已经安装好了 node.js v0.10.0. 我将要安装 Grunt.js v0.4.1.警告:如果你已经安装了 Gr ...
- ios 第3天
在手动引用计数中 每一次调用 retain retainCount 就会加一 每一次release retainCount就会减一 当retainCount 为零时 就会free (p) ; ...
- paddlepaddle初步印象
从其官网整理了一些资料如下: 1.基本概念 基本使用概念 PaddlePaddle是源于百度的一个深度学习平台.PaddlePaddle为深度学习研究人员提供了丰富的API,可以轻松地完成神经网络配置 ...
- [置顶]
针对 CoordinatorLayout 及 Behavior 的一次细节较真
我认真不是为了输赢,我就是认真.– 罗永浩 我一直对 Material Design 很感兴趣,每次在官网上阅读它的相关文档时,我总会有更进一步的体会.当然,Material Design 并不是仅仅 ...
- JMter参数化
参数化是干嘛的呢,咱们在调用接口的时候,有入参,那参数里面的值如果经常变化的话,就得每次去改了,很麻烦,这时候咱们就把需要经常变的值,改成可以变化的或者是咱们提前设置好的一些值,这样的话,调用的时候就 ...