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函数返 ...
随机推荐
- poj 1001 Exponentiation 第一题 高精度 乘方 难度:1(非java)
Exponentiation Time Limit: 500MS Memory Limit: 10000K Total Submissions: 138526 Accepted: 33859 ...
- qml 关于鼠标穿透的问题
最近在开发过程中,遇到了鼠标穿透的问题.结合网上给予的方法,都试了一圈,在这里总结一下: import QtQuick 2.9import QtQuick.Window 2.2import QtQui ...
- New Concept English three (22)
34w 54 Some plays are so successful that they run for years on end. In many ways, this is unfortunat ...
- Linux0.11信号处理详解
之前在看操作系统信号这一章的时候,一直是云里雾里的,不知道信号到底是个啥玩意儿..比如在看<Unix环境高级编程>时,就感觉信号是个挺神奇的东西.比如看到下面这段代码: #include& ...
- Shell 命令行统计 apache 网站日志访问IP以及IP归属地
Shell 命令行统计 apache 网站日志访问IP以及IP归属地 我的一个站点用 apache 服务跑着,积攒了很多的日志.我想用 shell 看看有哪些人访问过我的站点,并且他来自哪里. 因为日 ...
- 使用kibana来进行ElasticSearch的信息查询检索
大家经常会听到使用ELK搭建日志管理平台.完成日志聚合检索的功能,那么这个平台到底是个什么概念,怎么搭建,怎么使用呢? ELK包括ElasticSearch(数据存储.快速查询).logstash(日 ...
- 2.JSR简介 - JavaEE基础系列
JSR, Java Specification Request, Java规范请求; 也有的地方翻译为Java规范提案. 在前面的文章 1. Java EE简介 - JavaEE基础系列中, 简要介绍 ...
- VS2010对c++11的支持情况验证
目前仅仅测试工作中 使用的比较多的: 智能指针 shared_ptr #include <memory> std::shared_ptr<A> a(new A); ----支持 ...
- 利用你的Mission Control--设置快速回到桌面等操作
第一步:打开系统偏好设置 第二步:进入设置界面点击 Mission Control 第三:Mission Control界面 进入Hot corners(触发角) 第四:设置mac屏幕四个角的快捷键( ...
- day3 文件系统 内核模块 ctags
nfs网络文件系统 smb 修改配置文件 sudo vim /etc/samba/smb.conf 重启服务 /etc/init.d/samba restart 自制小的文件系统 1 ...