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函数返 ...
随机推荐
- C# ASP.NET 验证码
使用C# ASP.NET 获取 验证码的代码书写 一般都采用异步 点击 前台验证码图片 请求一次 : 前台图片代码: <img id="imgvalidatecode" sr ...
- js 计算时间
var date1=new Date(); //开始时间 var date2=new Date(); //结束时间 var date3=date2.getTime()-date1.getT ...
- PostgreSQL copy命令使用记录
上篇写到用pg_bulkload来导入数据,但是实际的环境是solaris,pg_bulkload还不支持,于是用copy的方式,下面附上脚本 -bash-4.1$ cat copy.sh #!/bi ...
- c# DataTable 导出csv文件
using System; using System.Data; using System.Configuration; using System.Collections.Generic; using ...
- Tornado 异步非阻塞
1 装饰器 + Future 从而实现Tornado的异步非阻塞 class AsyncHandler(tornado.web.RequestHandler): @gen.coroutine def ...
- css 中相对定位和绝对定位
1. css中定位机制有三种: 标准文档流, 浮动, 绝对定位 2. 绝对定位就属于第三种定位, 用到position属性, 下面就是具体设置 相对定位: 相对于自身原有位置(就是普通流的时候)进行偏 ...
- Andriod4.2 Camera 架构与实现
1.Camera架构包括客户端和服务端,他们之间的通信采用Binder机制实现. Camera的实现主要包括本地代码和Java代码两个层次: Camera本地框架: frameworks/native ...
- 用户空间与内核驱动的交互过程 — ioctl
在Linux内核模块的开发过程中,经常涉及到运行在用户空间上的应用程序与内核模块进行交互,ioctl系统调用是常用的一种方式.本文并不涉及vlan的具体原理,仅通过vconfig与vlan内核模块进行 ...
- TOF 初探
TOF 简介 TOF是Time of flight的简写,直译为飞行时间的意思.所谓飞行时间法3D成像,是通过给目标连续发送光脉冲,然后用传感器接收从物体返回的光,通过探测光脉冲的飞行(往返)时间来得 ...
- Ubuntu终端远程连接linux服务器
SSH是一个远程接入软件,可以让你想坐在计算机前面一样操作计算机.SSH使用加密方式传输数据,是一种非常安全的工作方式 步骤如下: 前提:如果没有安装ssh的话请 sudo apt-get inst ...