您的位置:首页 > 运维架构 > Linux

[转]Linux: wait和僵尸进程

2010-05-01 12:17 459 查看
之前我们已经讲到用fork()来创建一个新进程,用exit()来终止一个进程。现在我们将略微深入了解exit()执行之后发生的事情。­

事实上,exit()终止进程并没有将其彻底终结,而是将一个正常的进程变成了一个僵尸进程。该僵尸进程几乎不占用资源,没有可执行的代码,也不能被调度,仅仅只能在进程列表中保留一个位子。所以僵尸进程听似恐怖,实际上只能被后人凭吊而已
,但是却有它存在的实际价值。­

它的价值就在于它记载了已退出子进程的状态。这些状态包括进程是否是正常退出?所占有的cpu时间?进程ID?等等。说白了,僵尸进程之所以存在,就是为供其他进程收集已退出进程的信息用的。­

但是,linux的进程数是有上限的,进程列表中太多的“僵尸”为阻扰“新生命的”诞生。所以我们需要在收集它的信息后,将其彻底消灭。这时,我们就要用到wait()函数。­

pid_t wait(int *status)
pid_s是wait的返回值数据类型,status是一个指针,指向一个整形数据,status就是用来收集已退出进程的状态的,即僵尸进程的信息。其
执行过程是这样的:进程一旦执行wait,就立即阻塞自己,直到查找到已经变成僵尸的子进程,收集它的信息并将其彻底摧毁后返回,不然就一直阻塞,直到僵
尸子进程出现。­

假如我们不关心僵尸进程的信息,只想把它消灭,那么只要这样wait(NULL),只会返回子进程的ID号。正常情况下,wait收集已退出进程的状态,
并存入status中,它所指向的整数指出了是否是正常退出、以及正常结束时的返回值。对于这两方面的信息,我们用宏来表征: ­

WIFEXITED(status)用来指示子进程是否是正常退出,若是,则返回一个非零值。这里的status是wait(*status)中指针的对象。­

WEXITSTATUS(status)用来当子进程正常退出时,提取子进程的返回值即对应exit(*)中的值。­

由此可知,以上两个宏可以用来提取僵尸进程所记载的一部分状态信息。­

除了wait()函数来提取僵尸进程的信息并将其消灭之外,还有一个函数同样可以胜任这个工作。pid_t wait(pid_t
pid int *status
options),pid用来指定对应进程的ID,当它是-1时,则可以收集任僵尸何进程的信息;options中有用的选项是WNOHANG,当如是设
定时,那么waitpid不会和wait一样,一旦被执行就将进程阻塞知道僵尸出现为止,而是当没有僵尸时也返回,返回值是0,并不死等。所以wait实
际上是waitpid的特殊情况,即­

waitpid(-1,*status,0)。在执行正常的情况下,wait与waitpid都返回僵尸进程的ID。­

值得一提的是,如果父进程和子进程之间存在着协作关系,那就要对进程进行协调,使他们能按序进行。 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: