http://blog.csdn.net/yyyiran/article/details/19482525
2014.02
* 僵尸進(jìn)程
子進(jìn)程結束,父進(jìn)程沒(méi)有正確處理子進(jìn)程返回信息。
PS:直到父進(jìn)程退出,子進(jìn)程變?yōu)楣聝哼M(jìn)程,其父進(jìn)程會(huì )變?yōu)镮nit進(jìn)程(PPID=0),Init進(jìn)程會(huì )負責清理僵尸進(jìn)程
* 危害
僵尸進(jìn)程沒(méi)有從進(jìn)程列表刪除,占據內核資源
* 結論
多進(jìn)程編程,父進(jìn)程需要跟蹤子進(jìn)程的退出狀態(tài)
* 僵尸進(jìn)程查看方法:
1 top (zombie數量)
Tasks: 581 total, 1 running, 574 sleeping, 5 stopped,
1 zombie
2 ps -ef (defunct標記)
1022 16123 16122 0 11:32 pts/12 00:00:00 [a.out]
<defunct>
* 僵尸進(jìn)程處理方法:
當子進(jìn)程結束,其會(huì )給父進(jìn)程發(fā)送SIGCHLD信號。
這時(shí)父進(jìn)程捕獲信號后可調用wait()或者waitpid()函數回收子進(jìn)程尸體
1 pid_t wait (int * status);
2 pid_t waitpid(pid_t pid,int * status,int options);
PS:使用waitpid就夠了,其為wait提供非阻塞功能
PS:也可簡(jiǎn)單使用signal(SIGCHLD,SIG_IGN);這時(shí)內核在子進(jìn)程結束不會(huì )產(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;
- }
* 其他補充
PS:子進(jìn)程未結束,而父進(jìn)程先結束了,子進(jìn)程PPID變?yōu)?(Init進(jìn)程)。這時(shí)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