在父进程退出时终止子进程

时间:2012-09-14 15:24:35

标签: c parent-child kill zombie-process atexit

我对c和编程很新,需要一些帮助。在Linux上的c(cygwin)我需要在退出时删除所有子进程。我看过其他类似的问题,但无法让它发挥作用。我试过了 -

atexit(killzombies); //in parent process

void killzombies(void)
{
    printf("works");
    kill(0, SIGTERM);
    printf("works");
    if (waitpid(-1, SIGCHLD, WNOHANG) < 0)
         printf("works");
}

由于某种原因,“作品”甚至不打印。我按ctrl + c退出。

我也试过了 -

prctl(PR_SET_PDEATHSIG, SIGHUP); //in child process
signal(SIGHUP, killMe);

void killMe()
{
    printf("works");
    exit(1);
}

但是因为我正在使用cygwin,当我#include <sys/prctl.h>时,cygwin说它找不到文件或目录,我不知道要为它安装什么包。 另外,如果我的prctl()功能起作用,会杀死所有的僵尸吗?

我的程序是客户端服务器,我的服务器forks()来处理每个客户端。我想在服务器关闭时不留下任何剩下的僵尸。

3 个答案:

答案 0 :(得分:1)

你的waitpid没有提供通常的参数,我很惊讶它没有崩溃。原型是:

pid_t waitpid(pid_t pid, int *status, int options); 

第二个参数应该是{em>指针到int,您正在提供int。 另请注意,您应该为每个孩子致电waitpid,您只需拨打一个。

仅当您正常退出时才会调用

atexit()。如果您通过CTRL + C退出,那么您需要从SIGINT上的处理程序调用您的函数。

答案 1 :(得分:0)

来自atexit(3)的Linux文档:

  

如果使用atexit()(和on_exit(3))注册的函数,则不会调用   由于信号的传递,过程异常终止。

如果要在应用程序收到SIGINT或SIGTERM时进行清理,则需要安装相应的信号处理程序并在那里进行工作。

答案 2 :(得分:0)

您需要跟踪您的进程有多少子进程,然后多次调用wait。此外,正如其他人所说,如果进程被信号终止,则不会调用atexit()函数,因此您还需要从信号处理程序调用killzombies()。你需要这样的东西:

int n_children = 0; // global

void handle_sig(int sig) {
    killzombies();
    exit(sig);
}

// your atexit()
void killzombies() {
    kill(0, SIGKILL);
    while (n_children > 0) {
        if (wait(NULL) != -1) {
            n_children--;
        }
    }
}