Linux子进程的异步等待方式

我们知道当一个父进程创建一个子进程时,最好要调用wait或者waitpid函数等待子进程,不然会产生僵尸进程造成是内存泄漏的问题。一般父进程在等待子进程时有两种方式等待,一种是阻塞式等待,这时父进程不能处理自己的工作;另一种是以非阻塞式等待,父进程处理自己工作的同时,要定时去查看有没有子进程等待清理。

1.验证子进程在退出的时候会给父进程发送一个SIGCHLD信号

一般情况下父进程收到这个信号的默认处理是忽略这个信号,即就是不做任何处理,但是我们可以通过系统调用API:signal()来进行自定义处理句柄,进行验证,具体代码如下:
这里写图片描述

简单分析一下代码:子进程在打印一句话之后sleep3秒就退出,此时父进程中用一个for循环遍历捕捉32个普通信号,理论结果是子进程sleep3秒之后,父进程再sleep5秒,然后打印时候收到一个信号,结果如下:

这里写图片描述

执行kill -l命令查看所有信号结果如下(显然17号为SIGCHLD):
这里写图片描述

结果符合理论,所以我们确定子进程在推迟的时候会向父进程发送一个SIGCHLD信号,以供父进程进行相关处理,只不过默认情况下父进程忽略这个信号。

2.wait()和waitpid()的区别

<1>wait 函数:

  1. 用来等待任何一个子进程退出,由父进程调用。
  2. 返回值:成功返回被等待子进程的pid,失败返回-1。
  3. status:输出型参数,拿回子进程的退出信息。
  4. wait方式:阻塞式等待,等待的子进程不退出时,父进程一直不退出。
  5. 目的:回收子进程,系统回收子进程的空间。

如果参数status不为空,则进程终止状态被保存于其中。
依据传统,返回的整形状态字是由实现定义的,其中有些位表示退出状态(正常返回),其他位表示信号编号(异常返回),有一位表示是否产生了一个core文件等。
终止状态是定义在 sys/wait.h中的各个宏,有四可互斥的宏可以用来取得进程终止的原因。

WIFEXITED:正常返回时为真,可以执行宏函数 WEXITSTATUS获取子进程传送给exit、_exit或_Exit的参数的低8位。
WIFSIGNALED :异常返回时为真,可以执行宏函数WTERMSIG取得子进程终止的信号编号,另外,对于一些实现,定义有宏WCOREDUMP宏,若以经昌盛终止进程的core文件,则为真。
WIFSTOPPED :若为当前暂停子进程的返回的状态,则为真,可执行WSTOPSIG取得使子进程暂停的信号编号。
WIFCONTINUED:若在作业控制暂停后已经继续的子进程返回了状态,则为真,仅用于waitpid。

<2>waitpid:

  1. pid参数 :从参数的名字pid和类型pid_t中就可以看出,这里需要的是一个进程ID。但当pid取不同的值时,在这里有不同的意义。
  2. pid>0时,只等待进程ID等于pid的子进程,不管其它已经有多少子进程运行结束退出了,只要指定的子进程还没有结束,waitpid就会一直等下去。
  3. pid=-1时,等待任何一个子进程退出,没有任何限制,此时waitpid和wait的作用一模一样。
  4. 列表内容pid=0时,等待同一个进程组中的任何子进程,如果子进程已经加入了别的进程组,waitpid不会对它做任何理睬。
  5. pid<-1时,等待一个指定进程组中的任何子进程,这个进程组的ID等于pid的绝对值。
  6. status参数与wait()函数的基本相同,此处不再赘述。
  7. options参数
    当options参数为0时,与wait功能相同,仍是阻塞式等待,不提供额外功能,如果为下列常量按位或则提供更多功能:
    WCONTINUED:若实现支持作业控制,那么由pid指定的任一子进程在暂停后已经继续,但状态尚未报告,则返回状态
    WNOHANG:若由pid指定的子进程并不是立即可用的,则waitpid不阻塞,即此时以非阻塞方式(轮询式访问的必要条件)等待子进程,并且返回0。
  8. 当正常返回的时候,waitpid返回收集到的子进程的进程ID;
    如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0; 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在; 当pid所指示的子进程不存在,或此进程存在,但不是调用进程的子进程,waitpid就会出错返回,这时errno被设置为ECHILD;

有了上述的知识,我们编写如下代码:
这里写图片描述

结果(符合waitpid的描述,不再多说):
这里写图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值