reap linux zombie process 僵尸进程

来源:互联网 发布:个股数据查询 编辑:程序博客网 时间:2024/05/19 04:55

很多次碰到,或者听说过zombie/defunct process,都只是翻了一下资料,没有仔细看看这个东西。主要是涉及到了fork,signal,而这个一直没有用到,所以就懒得看。

http://en.wikipedia.org/wiki/Zombie_process,wikipedia上已经说得很明白,还有例子。对比起百度百科的说明http://baike.baidu.com/view/758736.htm,百科很多,但是大部分是堆砌和罗列。

百度上搜索到的linux zombie的相关信息,都是如何避免和解决zombie。而在开头会说明zombie如何产生,而这个是我一直都没有看明白。终于下定决心要把这个看明白一点。

以下代码在centos6.0 x86_64环境。

1. zombie.cpp 说明如何产生zombie process:

// g++ zombie.cpp -o zombie; ./zombie// to view the zombie://      ps axf|grep --color -in "zombie"#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <iostream>using namespace std;void child_progress(){    for(int i = 0; i < 5; i++){        sleep(1);        cout << "child #" << getpid() << ": in the child progress" << endl;    }    cout << "child #" << getpid() << ": exited!!!!!!!!!!!!!!!!zombie!!!!!!!!!!!!!!!!" << endl;    exit(0);}void main_progress(){    for(;;){        sleep(1);        cout << "parent #" << getpid() << ": in the parent progress" << endl;    }}int main(int argc, char** argv){    cout << "start a child progress..." << endl;    pid_t pid = 0;    pid = fork();    if(pid < 0){        cout << "create progress failed!" << endl;        exit(-1);    }    if(pid == 0){        child_progress();    }    else{        sleep(3);        main_progress();    }        return 0;}
2. dezombie-ignore.cpp 忽略SIGCHLD信号来避免zombie:

// g++ dezombie-ignore.cpp -o dezombie-ignore; ./dezombie-ignore#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>#include <sys/types.h>#include <sys/wait.h>#include <iostream>using namespace std;void child_progress(){    for(int i = 0; i < 5; i++){        sleep(1);        cout << "child #" << getpid() << ": in the child progress" << endl;    }    cout << "child #" << getpid() << ": exited!no zombie!!!!!!!!!!!!!!!!" << endl;    exit(0);}void main_progress(){    for(;;){        sleep(1);        cout << "parent #" << getpid() << ": in the parent progress" << endl;    }}int main(int argc, char** argv){    cout << "ignore the SIG_CHILD signal" << endl;    if(signal(SIGCHLD, SIG_IGN) < 0){        cout << "ignore signal failed!" << endl;        exit(-1);    }        cout << "start a child progress..." << endl;    pid_t pid = 0;    pid = fork();    if(pid < 0){        cout << "create progress failed!" << endl;        exit(-1);    }    if(pid == 0){        child_progress();    }    else{        sleep(3);        main_progress();    }        return 0;}
3.dezombie-signal.cpp 处理SIGCHLD来处理reap zombie:

// g++ dezombie-signal.cpp -o dezombie-signal; ./dezombie-signal#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>#include <sys/types.h>#include <sys/wait.h>#include <iostream>using namespace std;void child_progress(){    for(int i = 0; i < 5; i++){        sleep(1);        cout << "child #" << getpid() << ": in the child progress" << endl;    }    cout << "child #" << getpid() << ": exited!!!!!!!!!!!!!!!!zombie!!!!!!!!!!!!!!!!" << endl;    exit(0);}void main_progress(){    for(;;){        sleep(1);        cout << "parent #" << getpid() << ": in the parent progress" << endl;    }}void onSigChild(int sig){    int sleep_time = 10;    cout << "#" << getpid() << ": get a signal SIG_CHILD (a dead child). de-zombie in " << sleep_time << " seconds" << endl;    sleep(sleep_time);    int status;    pid_t pid = waitpid(-1, &status, WNOHANG);        if(pid < 0){        cout << "waitpid error!" << endl;        exit(-1);    }        if(pid == 0){        cout << "warning: no child terminated!" << endl;    }        cout << "child progress #" << pid << " terminated! de-zombie success!" << endl;}int main(int argc, char** argv){    cout << "register SIG_CHILD signal" << endl;    if(signal(SIGCHLD, onSigChild) < 0){        cout << "register signal failed!" << endl;        exit(-1);    }        cout << "start a child progress..." << endl;    pid_t pid = 0;    pid = fork();    if(pid < 0){        cout << "create progress failed!" << endl;        exit(-1);    }    if(pid == 0){        child_progress();    }    else{        sleep(3);        main_progress();    }        return 0;}
4. dezombie-2-fork.cpp 使用两次fork来避免zombie(怎么觉得这个方法很笨拙):

// g++ dezombie-2-fork.cpp -o dezombie-2-fork; ./dezombie-2-fork#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>#include <sys/types.h>#include <sys/wait.h>#include <iostream>using namespace std;void child_child_progress(){    for(int i = 0; i < 5; i++){        sleep(1);        cout << "child-child #" << getpid() << ": in the child progress" << endl;    }        cout << "child-child #" << getpid() << ": exited!no zombie!!!!!!!!!!!!!!!!" << endl;    exit(0);}void child_progress(){    cout << "child #" << getpid() << ": start a child-child progress." << endl;        pid_t pid = 0;    pid = fork();    if(pid < 0){        cout << "create progress failed!" << endl;        exit(-1);    }    if(pid == 0){        child_child_progress();    }    else{        cout << "child #" << pid << ": terminated! the child-child progress attach to init(1) progress!" << endl;    }}void main_progress(){    for(;;){        sleep(1);        cout << "parent #" << getpid() << ": in the parent progress" << endl;    }}int main(int argc, char** argv){    cout << "start a child progress..." << endl;    pid_t pid = 0;    pid = fork();    if(pid < 0){        cout << "create progress failed!" << endl;        exit(-1);    }    if(pid == 0){        child_progress();    }    else{        cout << "parent #" << getpid() << ": wait for child to exit in 1s" << endl;        sleep(1);        int status;        waitpid(pid, &status, 0);        cout << "parent #" << getpid() << ": the child progress exited!" << endl;        main_progress();    }        return 0;}

XP认为,代码是最好的文档。

准确点讲,应该是:精心构建的代码是最好的文档。

估计XP是假设所有代码都是精心写成的,毕竟一个人若愿意研究XP,肯定是代码基本功要过关。

原创粉丝点击