解决僵尸进程的两种方式(重温waitpid函数、了解17号信号SIGCHLD)

本文介绍了如何通过waitpid函数和SIGCHLD信号解决子进程僵尸问题,包括waitpid参数的用法、子进程退出信号的理解,以及使用SIGCHLD信号处理函数和设置SIG_IGN的两种方式,确保资源的有效回收。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

僵尸进程就是父进程创建了一个子进程,但是子进程退出以后,父进程在忙着干自己的事,没有回收子进程,导致子进程一直占用内存资源,这种情况我们称之为僵尸进程。

第一种方式,使用waitpid函数让父进程停下来等待子进程退出,并回收子进程,此时就能解决僵尸进程。在学习了进程信号以后,就有了第二种方式,子进程在退出的时候,会给父进程发送一个SIGCHLD信号,这个时候我们可以使用处理信号的知识来解决这个问题。


目录

一、waitpid函数

1、 第一个参数:准备回收的子进程的pid

2、第二个参数:输出型参数,获取子进程的退出状态

3、 第三个参数:进程等待的方式

二、SIGCHLD信号(17号信号)

1、方式一:在信号处理函数中,使用wait回收进程

 2、方式二:设置信号处理方式为SIG_IGN(仅适用于Linux)


一、waitpid函数

下面是waitpid函数的声明以及需要用到的头文件,我们要重点介绍的是,这个函数的参数

1、 第一个参数:准备回收的子进程的pid

如果填入的是子进程的pid,那么就会等待回收指定进程的pid

waitpid(19989, ... , ...);    //等待进程pid为19989的子进程

如果填入的是 -1,那么就会等待回收所有进程

2、第二个参数:输出型参数,获取子进程的退出状态

int status;
waitpid(-1 , &status , ... );

status不能简单的当作整型来看,要从二进制的角度来看,子进程正常退出时,子进程返回的是退出码异常退出时,子进程返回的是一个中止信号。status以二进制的形式保存了这两样东西,保存在低16位,即0~15位,其中 0~6 保存中止信号,7 是core dump标志位,8~15是保存退出码

想要详细了解的可以看看下面博客中的 “关于status

进程(五)—— 进程退出、进程等待(含waitpid函数)_abs(ln(1+NaN))的博客-优快云博客僵尸进程是子进程运行结束,但因为没有被回收,所以一直占用资源,为了解决这个问题,引入了进程终止和进程等待。进程终止能让子进程在执行完任务以后,立马退出进程;进程等待让父进程停下来等待子进程执行完毕,然后回收子进程https://blog.youkuaiyun.com/challenglistic/article/details/123882574

3、 第三个参数:进程等待的方式

进程的等待方式分为阻塞等待非阻塞等待,阻塞等待就是执行waitpid以后,父进程啥也不干,干等着,等回收完子进程再继续向下运行;非阻塞等待就是执行waitpid以后,每隔一段时间,检测一下子进程是否退出,如果退出了,就回收,没退出,就继续干自己的事。

想要详细了解的可以看看下面博客中的 “进程阻塞等待的方式”、“进程非阻塞等待的方式”(内含测试代码

进程(五)—— 进程退出、进程等待(含waitpid函数)_abs(ln(1+NaN))的博客-优快云博客僵尸进程是子进程运行结束,但因为没有被回收,所以一直占用资源,为了解决这个问题,引入了进程终止和进程等待。进程终止能让子进程在执行完任务以后,立马退出进程;进程等待让父进程停下来等待子进程执行完毕,然后回收子进程https://blog.youkuaiyun.com/challenglistic/article/details/123882574

二、SIGCHLD信号(17号信号)

1、方式一:在信号处理函数中,使用wait回收进程

waitpid阻塞方式等待的弊端就是,父进程阻塞了,就不能干自己的事了;waitpid非阻塞等待的弊端是,在处理自己的事的同时需要时不时检测一下子进程是否退出,程序实现比较复杂。

实际上子进程在退出的时候,会给父进程发送SIGCHLD信号,默认动作是忽略(handler表填的是SIG_DFL),父进程可以自定义SIGCHLD的信号处理函数,这样的话,就可以专注于自己的工作,不必关心子进程的退出了

下面是测试代码

预期效果是,3s以后子进程退出,父进程一直在干自己的事,既没有阻塞,实现起来也不是特别复杂,最重要的是不会出现僵尸进程,下面我们会从代码结果的角度、进程变化的角度观察

 刚开始进程是这样

 随后会变成下面这样,自始至终没有出现过Z状态

 2、方式二:设置信号处理方式为SIG_IGN(仅适用于Linux)

除了上述的处理方式外,还有一种更为简单的方式,一开始17号信号选择的是默认处理方式SIG_DFL,我们可以把17号的处理方式显式的设置为SIG_IGN,表明父进程不关心子进程的退出信息,只要回收了就就行

 ​​​​测试结果如下,依然没有出现 僵尸进程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值