歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux之僵屍進程

* 僵屍進程
子進程結束,父進程沒有正確處理子進程返回信息。
PS:直到父進程退出,子進程變為孤兒進程,其父進程會變為Init進程(PPID=0),Init進程會負責清理僵屍進程

* 危害
僵屍進程沒有從進程列表刪除,占據內核資源

* 結論
多進程編程,父進程需要跟蹤子進程的退出狀態

* 僵屍進程查看方法:
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>

* 僵屍進程處理方法:
當子進程結束,其會給父進程發送SIGCHLD信號。
這時父進程捕獲信號後可調用wait()或者waitpid()函數回收子進程屍體
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);這時內核在子進程結束不會產生僵屍進程

* 編程例子

#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:子進程未結束,而父進程先結束了,子進程PPID變為0(Init進程)。這時ps -ef子進程並不是僵屍態
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

Copyright © Linux教程網 All Rights Reserved