C叉在一个while循环[连续检查一些东西并分叉一个孩子并杀死另一个]

时间:2014-01-14 00:39:00

标签: c linux fork

说我的代码是这样的(C,Linux):

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <signal.h>
#include <unistd.h>

void zombie1(void)
{
    while(1)
    {
        // do_some_stuff;
    }
}

void zombie2(void)
{
    while(1)
    {
        // do_some_stuff;
    }
}

int which_zombie(void)
{
    check_for_this_or_that();

    if(this_happened)
    {
        return 1;
    }
    else if(that_happened)
    {
        return 2;
    }
}

int main(void){

    // fork()
    // here i want to call which_zombie() every 10 seconds and run one of the zombies
    // and kill the other one...    
}

在主要流程保持不变的情况下如何做到这一点?在main函数内部,我正在调用fork(),在子进程中我调用了which_zombie,如果其中一个已经存在则杀死它并运行另一个。我试过这个但没有成功! :

int main(void)
{
    int pid = fork();

    if(pid == 0)
    {
        int type;
        int zombie1_pid = 0;
        int zombie2_pid = 0;
        while(1)
        {
            type = which_zombie();
            if(type == 1)
            {
                if(zombie2_pid != 0)
                {
                    kill(zombie2_pid, SIGTERM);
                    zombie2_pid = 0;
                }

                zombie1_pid = fork();
                if(zombie1_pid == 0)
                {
                    zombie1();
                }

            }
            else if(type == 2)
            {
                if(zombie1_pid != 0)
                {
                    kill(zombie1_pid, SIGTERM);
                    zombie1_pid = 0;
                }

                zombie2_pid = fork();
                if(zombie2_pid == 0)
                {
                    zombie2();
                }

            }


            sleep(10);
        }
    }
    else
    {
        // parent ...
    }
}

从手册页(waitpid)我发现应该在某个地方添加对waitpid的调用[孩子们仍然处于僵尸状态]。那么这段代码有什么问题呢?


EDIT1: 为了清楚起见,程序应该在while循环中每隔10秒检查一次“type”,并根据类型检查fork func1或func2,每次如果类型改变它会杀死子进程并“fork”另一个。当然,当我们关闭父级时,所有子进程也应该退出... 谢谢你。


EDIT2: 克里斯的回答解决了这个问题,但为了杀死所有的孩子,让父母保持活着,我发现我应该像这样添加一个信号处理程序:

pid_t parent_pid;

void sigquit_handler(int sig)
{
    assert(sig == SIGQUIT);
    pid_t self_pid = getpid();
    if(parent_pid != self_pid)
    {
        _exit(0);
    }
}

主要

    parent_pid = getpid();
    signal(SIGQUIT, sigquit_handler);
    kill(-parent_pid, SIGQUIT);
    int status;
    int i;


        for(;;)
        {
            pid_t child = wait(&status);
            if(child > 0 && WIFEXITED(status) && WEXITSTATUS(status) == 0)
            {
                printf("child %d exited successfully.\n", (int)child);
            }
            else if(child < 0 && errno == EINTR)
            {
                continue;
            }
            else{
                perror("wait");
                abort();
            }
            break;
    }

1 个答案:

答案 0 :(得分:1)

你好像创造了一种叉炸弹。确实,如果你偶尔不使用waitpid(),一堆失效的进程将开始堆积。

int main(void)
{
    int zpid = -1, type, oldtype=0;

    while(1) {
        type = which_zombie();
        if (type != oldtype) {
            if (zpid != -1)
                    kill(zpid, SIGTERM);
            zpid = fork();
            if (zpid == 0) {
                if (type == 1)
                    zombie1();
                else
                    zombie2();
            }
            oldtype = type;
        }
        waitpid(-1, NULL, WNOHANG);
        sleep(10);
    }
}