分叉,共享变量,&处理僵尸进程

时间:2012-02-12 20:07:21

标签: c fork zombie-process

我正在为一些功课编写一个程序,这将需要一些分支,但我对分享变量和处理僵尸进程有点不清楚。

  1. 如果我有全局变量,那么父和所有子项是否都使用这些全局变量的相同“副本”?如果没有,是否有某些方法可以让他们(vfork?)?

  2. 我知道僵尸进程是什么,但我不清楚如何摆脱它们。我的程序将分散大量临时进程,所以我不知道我可以wait()为每个进程单独进行。当父进程终止时,它会删除与之关联的所有僵尸,对吧?如果父母在孩子面前被终止怎么办?孩子完成后是否会留下僵尸(这些是init()定期清除的那些?)

  3. 可能完全回避问题2,因为我实际上并不关心子进程的结果,有没有办法让他们不留下僵尸?我看到了signal(SIGCHLD, SIG_IGN)的一些内容,但我不确定如何使用它,我发现它的手册页有点迟钝。

2 个答案:

答案 0 :(得分:4)

  

1)如果我有全局变量,那么父和所有子项是否都使用这些全局变量的相同“副本”?如果没有,有什么方法可以让他们(vfork?)?

将完全复制堆栈。复制,不共享。因此,如果您希望父母和孩子进行通信,则必须使用套接字或共享内存。或线程。

跳过问题2:

  

3)可能完全回避问题2,因为我实际上并不关心子进程的结果,有没有办法让他们根本不留下僵尸?我看到了一些关于信号的信息(SIGCHLD,SIG_IGN),但我不确定如何使用它,而我找到的那个人有点......愚蠢。

在POSIX中,您可以为程序使用特殊信号。例如,ctrl + c将发送一个中断信号(SIGINT),如果你没有定义一个SIGINT处理程序,它将终止你的程序。

SIGCHLD是您的程序在子进程终止时收到的信号。默认情况下会被忽略。那么,为什么我们不写自己的小信号处理程序呢?信号处理程序是一个void函数,只有int作为参数:

void cleanup_child(int signal) {
    wait();
}

现在在主函数的最开始处注册信号处理程序并完成:

int main(...){
    signal(SIGCHLD,cleanup_child);
    ...

现在所有的僵尸都会自动清理。请记住,信号会中断当前程序,调用特定信号处理程序并恢复程序。

答案 1 :(得分:1)

1)这两个进程不共享全局变量。

2)使用waitid (2)可能会对您有所帮助。看男人

如果父进程在子进程之前终止,则子进程将获得新的父进程 - PID为1的进程,即init。如果孩子是僵尸,init会自动解决此问题。