轉(zhuǎn)載請(qǐng)注明:http://www.coder4.com/index.php
/archives/151
首先特別感謝這篇文章給的啟發(fā)!
http://hi.baidu.com/%D3%EA%BA%E7%D1%F4/blog/item/6490202aaba49193023bf633.html
對(duì)原作者表示敬意和膜拜!
fork()之后,非阻塞(異步)等待子進(jìn)程(回收僵尸)。
fork()之后,子進(jìn)程和父進(jìn)程分叉執(zhí)行,僵尸進(jìn)程的產(chǎn)生是因?yàn)楦高M(jìn)程沒有給子進(jìn)程“收尸”造成的,又可以根據(jù)危害程度分為下述兩類:
總體來說:當(dāng)子進(jìn)程結(jié)束之后,但父進(jìn)程未結(jié)束之前,子進(jìn)程將成為僵尸進(jìn)程。
(1)當(dāng)子進(jìn)程結(jié)束之后,但父進(jìn)程未結(jié)束之前,子進(jìn)程將成為僵尸進(jìn)程,父進(jìn)程結(jié)束后僵尸被init進(jìn)程回收。
(2)如果子進(jìn)程結(jié)束了,但是父進(jìn)程始終沒有結(jié)束,那么這個(gè)僵尸將一直存在,而且隨著exec,僵尸越來越多。
如下面的代碼,在父進(jìn)程執(zhí)行的5s內(nèi),子進(jìn)程將為僵尸:
25 |
printf ( "The child process is %d\n" , c_pid); |
30 |
printf ( "I 'm a child.\n" ); |
如上面的代碼,在父進(jìn)程的5s內(nèi),子進(jìn)程一直是僵尸!
因此,需要對(duì)僵尸進(jìn)程進(jìn)行回收,傳統(tǒng)的回收方法是,使用wait()函數(shù),等待子進(jìn)程,wait()是阻塞模式的,當(dāng)子進(jìn)程沒有結(jié)束之前,wait一直等
待,不往下面的語句執(zhí)行。
26 |
printf ( "The child process is %d\n" , c_pid); |
29 |
if ((pid =
wait(&status)) != -1 && pid == c_pid) { |
31 |
printf ( "The child exit with %d\n" , WEXITSTATUS(status)); |
34 |
printf ( "wait() fail.\n" ); |
36 |
printf ( "Now , The child has
been exit , and I will sleep.\n" ); |
41 |
printf ( "I 'm a child.\n" ); |
轉(zhuǎn)載自:4號(hào)程序員
如上面的代碼,在子進(jìn)程執(zhí)行5秒后,即被回收,在夫進(jìn)程的20秒內(nèi),子進(jìn)程已經(jīng)被結(jié)束,不再是僵尸。
但是這種利用wait()阻塞等待的方法也有一定的缺陷,那就是父進(jìn)程必須等待子進(jìn)程,無法做其他事情,如何非阻塞的等待子進(jìn)程呢?
man wait,查看NOTES章節(jié),可以找到:
子進(jìn)程退出的時(shí)候,會(huì)發(fā)送SIGCHLD信號(hào),默認(rèn)的POSIX不響應(yīng),所以,我們只需要把處理SIGCHLD的函數(shù)自己實(shí)現(xiàn)就OK了,怎么作呢?
signal用于設(shè)置處理信號(hào)量的規(guī)則(或跳轉(zhuǎn)到的函數(shù))
1 |
signal (SIGCHLD,handler); |
6 |
int pid =
waitpid(-1,&status,WNOHANG); |
9 |
printf ( "The child exit with code %d" ,WEXITSTATUS(status)); |
OK,全部代碼如下,注意父進(jìn)程不要再用wait阻塞啦!
18 |
void handler( int num) { |
21 |
int pid = waitpid(-1, &status,
WNOHANG); |
22 |
if (WIFEXITED(status)) { |
23 |
printf ( "The child %d exit with code %d\n" , pid, WEXITSTATUS(status)); |
32 |
signal (SIGCHLD, handler); |
37 |
printf ( "The child process is %d\n" , c_pid); |
40 |
for ( int i = 0; i < 10; i++) { |
41 |
printf ( "Do parent things.\n" ); |
48 |
printf ( "I 'm a child.\n" ); |
posted on 2010-03-30 11:27
chatler 閱讀(394)
評(píng)論(0) 編輯 收藏 引用 所屬分類:
Linux_Coding