子进程的异步等待方式

2017-06-12 13:46 阅读 235 次 评论 0 条

你是否还记得僵尸进程呢?当时我们是调用wait和waitpid函数清理掉僵尸进程,这属于父进程阻塞式等待(wait/waitpid可以设置参数变成非阻塞)子进程结束的范畴,当然,也可以非阻塞式地查询子进程结束等待清理(即轮询方式),这就好比我在烧水的时候,还能抽空看一本《C和指针》,每隔一段时间去检查一下水是否烧开。

验证子进程退出时向父进程发送信号

在Linux(CentOS6.5或其他)环境下,子进程终止时会给父进程发送SIGCHLD信号,我们之所以在之前的父子进程退出时未发现信号,原因在于SIGCHLD信号的默认动作为忽略

为了验证子进程在退出时确实向父进程发送了SIGCHLD信号,我们对SIGCHLD信号进行捕捉,让父进程fork出子进程,子进程sleep3秒之后调用exit(1)终止,父进程自定义SIGCHLD信号的处理函数。

从结果可以看出:24480为子进程的pid,24479为父进程的pid,3秒之后子进程退出并打印父进程的自定义捕捉函数,即验证了子进程向父进程发送了SIGCHLD信号

父进程等待子进程的异步机制

我们在进入异步之前,先对waitpid的各项参数作以说明,它的原型如下:

参数pid依具体值的不同含义(英语不好很糟糕):

pid = -1:等待任何一个子进程,与wait相同。

pid = 0:等待与调用者进程组id相同的任意子进程。

pid > 0:等待进程id与pid值相同的子进程。

pid < - 1:等待进程组id与pid绝对值相等的任意子进程。

参数option依具体值的不同含义:

WNOHANG:非阻塞式等待指定的进程。

WUNTRACED:如果子进程进入暂停执行则马上返回,但结束状态不予以例会。

WCONTINUED:若实现支持作业控制,那么由pid指定的任一子进程在暂停后已经继续,但状态尚未报告,则返回状态。

下面这个例子是一个反例,当我们将waitpid的第一个参数设置为-1,最后一个参数设置为0,则表示等待任意一个子进程,与wait一致,属于阻塞式等待

下面这个例子才是真正意义上的异步等待机制:即非阻塞式等待(轮询方式),当子进程退出时会向父进程发送一个SIGCHLD信号,父进程再去回收子进程,其他情况父进程将干自己的事。

我们将waitpid的第三个参数设置为WNOHANG非阻塞式等待任何一个子进程,下列程序中我们fork了三个子进程:

从结果可以看出:子进程1等待1秒后退出,子进程2等待2秒后退出,退出时发送SIGCHLD信号给父进程。子进程3正常运行,则父进程非阻塞式等待而去执行自己的工作

版权声明:本文著作权归原作者所有,欢迎分享本文,谢谢支持!
转载请注明:子进程的异步等待方式 | 术与道的分享
分类:操作系统 标签:, ,
1024do.com导航_术与道导航平台

发表评论


表情