Loading... 我们有这样一个问题:孤儿进程和僵尸进程,怎么产生的?有什么危害?怎么去预防? 下面是针对此问题的总结与概括。 ### 一、产生的原因 ##### 一般进程 正常情况下:子进程由父进程创建,子进程再创建新的进程。父子进程是一个异步过程,父进程永远无法预测子进程的结束,所以,当子进程结束后,它的父进程会调用`wait()`或`waitpid()`取得子进程的终止状态,回收掉子进程的资源。 ##### 孤儿进程 孤儿进程:父进程结束了,而它的一个或多个子进程还在运行,那么这些子进程就成为孤儿进程(`father died`)。子进程的资源由`init`进程(进程号`PID = 1`)回收。 ##### 僵尸进程 僵尸进程:子进程退出了,但是父进程没有用`wait`或`waitpid`去获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中,这种进程称为僵尸进程。 ### 二、问题危害 注意:`unix`提供了一种机制保证父进程知道子进程结束时的状态信息 这种机制是:在每个进程退出的时候,内核会释放所有的资源,包括打开的文件,占用的内存等。但是仍保留一部分信息(进程号`PID`,退出状态,运行时间等)。直到父进程通过`wait`或`waitpid`来取时才释放。 但是这样就会产生问题:如果父进程不调用`wait`或`waitpid`的话,那么保留的信息就不会被释放,其进程号就会被一直占用,但是系统所能使用的进程号是有限的,如果大量产生僵死进程,将因没有可用的进程号而导致系统无法产生新的进程,这就是僵尸进程的危害 孤儿进程是没有父进程的进程,它由`init`进程循环的`wait()`回收资源,`init`进程充当父进程。因此孤儿进程并没有什么危害。 补充:任何一个子进程(`init`除外)在`exit()`之后,并非马上就消失掉,而是留下一个称为僵尸进程的数据结构,等待父进程去处理。如果父进程在子进程`exit()`之后,没有及时处理,出现僵尸进程,并可以用`ps`命令去查看,它的状态是`“Z”`。 三、解决方案 1. `kill`杀死元凶父进程(一般不用) 严格的说,僵尸进程并不是问题的根源,罪魁祸首是产生大量僵死进程的父进程。因此,我们可以直接除掉元凶,通过`kill`发送`SIGTERM`或者`SIGKILL`信号。元凶死后,僵尸进程进程变成孤儿进程,由`init`充当父进程,并回收资源。 或者运行:`kill -9` 父进程的`pid`值、 2. 父进程用`wait`或`waitpid`去回收资源(方案不好) 父进程通过`wait`或`waitpid`等函数去等待子进程结束,但是不好,会导致父进程一直等待被挂起,相当于一个进程在干活,没有起到多进程的作用。 3. 通过信号机制,在处理函数中调用`wait`,回收资源 通过信号机制,子进程退出时向父进程发送`SIGCHLD`信号,父进程调用`signal(SIGCHLD,sig_child)`去处理`SIGCHLD`信号,在信号处理函数``sig_child()`中调用`wait`进行处理僵尸进程。什么时候得到子进程信号,什么时候进行信号处理,父进程可以继续干其他活,不用去阻塞等待。 注:“`SIGCHLD`”是“`SIGnal: CHiLD exit`”的缩写 最后修改:2022 年 08 月 05 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 0 如果觉得我的文章对你有用,请随意赞赏