2

我正在为一些需要分叉的作业编写程序,但我对共享变量和处理僵尸进程有点不清楚。

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

  2. 我知道僵尸进程是什么,但我不清楚如何摆脱它们。我的程序将分离出许多临时进程,所以我不知道我可以wait()单独处理每个进程。当父进程终止时,它会清除与之相关的所有僵尸,对吗?如果父母在孩子之前终止怎么办?孩子完成后会留下一个僵尸吗(这些是init()定期清除的)吗?

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

4

2 回答 2

5

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

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

跳过问题2:

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

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

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

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

现在在您的主要功能的最开始注册您的信号处理程序并完成:

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

Now all zombies get cleaned automatically. Please keep in mind that a signal interrupts your current program, calls the specific signal handler and resumes your program.

于 2012-02-12T20:20:39.207 回答
1

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

2)使用waitid (2)可以帮助你。看人。

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

于 2012-02-12T20:15:07.020 回答