我正在为一些功课编写一个程序,这将需要一些分支,但我对分享变量和处理僵尸进程有点不清楚。
如果我有全局变量,那么父和所有子项是否都使用这些全局变量的相同“副本”?如果没有,是否有某些方法可以让他们(vfork
?)?
我知道僵尸进程是什么,但我不清楚如何摆脱它们。我的程序将分散大量临时进程,所以我不知道我可以wait()
为每个进程单独进行。当父进程终止时,它会删除与之关联的所有僵尸,对吧?如果父母在孩子面前被终止怎么办?孩子完成后是否会留下僵尸(这些是init()
定期清除的那些?)
可能完全回避问题2,因为我实际上并不关心子进程的结果,有没有办法让他们不留下僵尸?我看到了signal(SIGCHLD, SIG_IGN)
的一些内容,但我不确定如何使用它,我发现它的手册页有点迟钝。
答案 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
会自动解决此问题。