僵尸进程

来源:互联网 发布:偶得作诗软件 编辑:程序博客网 时间:2024/06/14 15:54

什么是僵尸进程?

首先要说说Linux下进程的几种状态,这在任何一本将Linux内核的书里面都可以看到,不同于教科书,具体设计一个操作系统的时候要考虑到实用性,所以Linux里面进程的状态要更实际一些,创建是不需要状态的:

1、可执行状态(TASK_RUNNING):相当于把教科书里面的就绪态和运行态放在了一块

2、可中断的睡眠状态(TASK_INTERRUPTIBLE):相当于教科书里面的睡眠状态

3、不可中断的睡眠状态(TASK_UNINTERRUPTIBLE):这个很少用

4、暂停状态(TASK_STOPPED):进程的执行被暂停

5、跟踪状态(TASK_TRACED):当另一个进程被另一个进程监控时,相当于为了调试用的

6、僵死状态(EXIT_ZOMBIE):一种特殊的状态,PCB还在,看是进程占有的资源不在了

7、僵死撤销状态(EXIT_DEAD):相当于教科书里面的终止状态

一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他, 那么他将变成一个僵尸进程,换句话说,如果一个进程结束后,他的pcb没有被回收,那么他就会变成一个。

Linux为什么要弄一个僵死状态?

由于子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程到底什么时候结束.那么会不会因为父进程太忙来不及wait子进程,或者说不知道子进程什么时候结束,而丢失子进程结束时的状态信息呢?不会。因为UNⅨ提供了一种机制可以保证只要父进程想知道子进程结束时的状态信息,就可以得到。这种机制就是:在每个进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等。但是仍然为其保留一定的信息(包括进程号the process ID,退出状态the termination status of the process,运行时间the amount of CPU time taken by the process等)。直到父进程通过wait/waitpid来取时才释放.但这样就导致了问题,如果进程不调用wait/waitpid的话,那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免。

如果避免僵尸进程

1、父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起。

2、如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后, 父进程会收到该信号,可以在handler中调用wait回收。

3、如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCHLD,SIG_IGN) 通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收, 并不再给父进程发送信号。

4、还有一些技巧,就是fork两次,父进程fork一个子进程,然后继续工作,子进程fork一 个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收 还要自己做。

原创粉丝点击