reap linux zombie process 僵尸进程

很多次碰到,或者听说过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,肯定是代码基本功要过关。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

winlinvip

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值