博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SIGCHLD信号与进程异步等待
阅读量:4149 次
发布时间:2019-05-25

本文共 1122 字,大约阅读时间需要 3 分钟。


进程等待


首先,让我们先来回顾一下有关进程等待的知识。

所谓进程等待,说的就是父进程等待子进程:

2

如图,父进程调用wait和waitpid函数等待子进程,从而清理系统中的僵尸进程。在此过程中,父进程可以阻塞等待子进程结束,也可以非阻塞地查询是否有子进程结束等待清理(也就是轮询的方式)

若采用阻塞等待方式,父进程就不能处理自己的工作了;采用非阻塞方式,父进程在处理自己工作的同时还要时不时地轮询⼀下子进程状态,程序实现复杂。


SIGCHLD信号


SIGCHLD是linux系统信号列表中定义的第17号信号:

1

事实上,进程等待不只是上面描述的那样,子进程在终止时会给父进程发SIGCHLD信号,因为⼦进程终止是一个异步事件,所以发生这种信号也是内核向父进程发的异步通知。而大多数父进程对该信号的默认处理动作是忽略。

尽管如此,父进程还是可以自定义SIGCHLD信号的处理函数,这样它只需专心处理自己的工作,而不必关⼼子进程了, 子进程终止时会通知父进程,父进程在信号处理函数中调用wait清理子进程即可。


Code


有了进程等待和SIGCHLD信号的概念,接下来利用SIGCHLD信号编写代码实现父进程对子进程的异步等待

1.验证子进程退出时会给父进程发送SIGCHLD信号的机制

代码:先创建子进程,然后使其直接退出。再让父进程调用waitpid和signal函数等待子进程并捕捉子进程发送的17号信号

3

运行结果:

4

结果表明,父进程id为14924的进程确实受到了其子进程退出时发送的17号信号。

2.编写父进程等待子进程的异步版本

上边父进程在等待子进程成功后直接退出,现在我们要实现父进程等待子进程成功后,继续做自己的事情。这就是异步等待。

代码:

在捕捉函数里加入while循环,使得在程序中有多个子进程时,父进程就会一直等待所有子进程退出(id > 0)

5

先让父进程运行,5秒之后子进程退出。父进程等待成功后,继续做自己的事情。

6

运行结果:

7

可以看出,情况如预料的那样。实现了父进程对子进程的异步等待。

但这里有一个问题,如果有子进程一直不退出,那么父进程就会一直阻塞等待。这显然是我们不愿看到的。所以为了解决这个问题,对捕捉函数handler修改如下:

8

在上面的代码中,对waitpid函数的宏参数WNOHANG进行设置,实现非阻塞等待。0和-1都是其可能的返回值,返回0表示没有子进程可以等,返回-1表示函数调用失败。这样就避免了父进程的阻塞等待。所以在while循环里再加入了switch选择分支结构。增强代码的健壮性。

再次运行程序,结果依然无误:

9


The End


关于linux中的信号,以后也会有博文介绍,敬请期待。。。

你可能感兴趣的文章
Java的Properties配置文件用法【续】
查看>>
JAVA操作properties文件的代码实例
查看>>
IPS开发手记【一】
查看>>
Java通用字符处理类
查看>>
文件上传时生成“日期+随机数”式文件名前缀的Java代码
查看>>
Java代码检查工具Checkstyle常见输出结果
查看>>
北京十大情人分手圣地
查看>>
Android自动关机代码
查看>>
Android中启动其他Activity并返回结果
查看>>
2009年33所高校被暂停或被限制招生
查看>>
GlassFish 部署及应用入门
查看>>
X-code7 beta error: warning: Is a directory
查看>>
Error: An App ID with identifier "*****" is not avaliable. Please enter a different string.
查看>>
3.5 YOLO9000: Better,Faster,Stronger(YOLO9000:更好,更快,更强)
查看>>
iOS菜鸟学习--如何避免两个按钮同时响应
查看>>
iOS菜鸟学习—— NSSortDescriptor的使用
查看>>
CORBA links
查看>>
如何使用BBC英语学习频道
查看>>
初识xsd
查看>>
java 设计模式-职责型模式
查看>>