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函数返 ...
随机推荐
- web版源码管理软件SCM-Manager安装配置
背景 一直使用 “VisualSvn Server” 作为源码管理工具,使用一段时间之后,使用场景遇到以下问题 添加用户必需登录到服务器. 一台服务器,只能安装一个 “VisualSvn Server ...
- 官方文档-Linux服务器集群系统(一)
转载-Linux服务器集群系统(一) LVS项目介绍 章文嵩 (wensong@linux-vs.org)2002 年 3 月 本文介绍了Linux服务器集群系统--LVS(Linux Virtual ...
- 《APUE》第7章 进程环境-读书笔记
一.main函数. main函数的原型如下.argc是命令行参数的数目,argv是指向参数的各个指针所构成的数组. int main(int argc, char *argv[]) 当内核执行C程序时 ...
- New Concept English there (7)
27w/m Has it ever happened to you? Have you ever put your trousers in the washing machine and then r ...
- OGG到OGGAdapter配置详情-从Oracle直接抽取成csv文件
Oracle Golden Gate是Oracle旗下一款支持异构平台之间高级复制技术,是Oracle力推一种HA高可用产品,简称“OGG”,可以实现Active-Active 双业务中心架构 1.1 ...
- java事务(一)
Java中事务处理的基本方法与原理,包含以下文章: (一)Java事务处理的基本问题 (二)失败的案例 (三)丑陋的案例 (四)成功的案例(自己实现一个线程安全的TransactionManager) ...
- C#中正则表达式编程(未完,待补充)
对于只存储一个匹配,可用Match类: 一般模式: Regex reg = new Regex(string pattern); string str = "###############& ...
- slack 团队协作平台
/**************************************************************************** * slack 团队协作平台 * 说明: * ...
- java之接口
背景 为了防止[多重继承]:(在面向对象的编程语言(例如java)中,指一个类可以同时继承多个父类的行为和特征功能)所引发的"致命方块",出现了接口. 使用 定义 public ...
- spi总结
SPI的四种模式 SPI的相位(CPHA)和极性(CPOL)分别可以为0或1,对应的4种组合构成了SPI的4种模式(mode) Mode 0:CPOL = 0,CPHA = 0 Mode 1:CPOL ...