http://blog.csdn.net/yyyiran/article/details/19482525
2014.02
* 僵尸進(jìn)程
子進(jìn)程結(jié)束,父進(jìn)程沒有正確處理子進(jìn)程返回信息。
PS:直到父進(jìn)程退出,子進(jìn)程變?yōu)楣聝哼M(jìn)程,其父進(jìn)程會變?yōu)镮nit進(jìn)程(PPID=0),Init進(jìn)程會負(fù)責(zé)清理僵尸進(jìn)程
* 危害
僵尸進(jìn)程沒有從進(jìn)程列表刪除,占據(jù)內(nèi)核資源
* 結(jié)論
多進(jìn)程編程,父進(jìn)程需要跟蹤子進(jìn)程的退出狀態(tài)
* 僵尸進(jìn)程查看方法:
1 top (zombie數(shù)量)
Tasks: 581 total, 1 running, 574 sleeping, 5 stopped,
1 zombie
2 ps -ef (defunct標(biāo)記)
1022 16123 16122 0 11:32 pts/12 00:00:00 [a.out]
<defunct>
* 僵尸進(jìn)程處理方法:
當(dāng)子進(jìn)程結(jié)束,其會給父進(jìn)程發(fā)送SIGCHLD信號。
這時父進(jìn)程捕獲信號后可調(diào)用wait()或者waitpid()函數(shù)回收子進(jìn)程尸體
1 pid_t wait (int * status);
2 pid_t waitpid(pid_t pid,int * status,int options);
PS:使用waitpid就夠了,其為wait提供非阻塞功能
PS:也可簡單使用signal(SIGCHLD,SIG_IGN);這時內(nèi)核在子進(jìn)程結(jié)束不會產(chǎn)生僵尸進(jìn)程
* 編程例子
- #include <iostream>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- using namespace std;
-
- void OnSigChild(int iSig)
- {
- pid_t iPid;
- int iStat;
- while ((iPid = waitpid(-1, &iStat, WNOHANG)) > 0)
- {
- cout << "<OnSigChild>, Pid=" << iPid << endl;
- }
- }
-
- int main()
- {
- signal(SIGCHLD, OnSigChild);
- if (!fork())
- {
- // Child
- cout << "Child:" << getpid() << endl;
- exit(0);
- }
-
- // Parent
- while(1);
- return 0;
- }
* 其他補(bǔ)充
PS:子進(jìn)程未結(jié)束,而父進(jìn)程先結(jié)束了,子進(jìn)程PPID變?yōu)?(Init進(jìn)程)。這時ps -ef子進(jìn)程并不是僵尸態(tài)
gapp_devnet_1:~ # ps -ef | grep 18849
UID PID PPID C STIME TTY TIME CMD
1022 18849 1 0 11:35 pts/12 00:00:00 ./a.out