使用vfork实现双重fork

3

你好
我正在编写一个服务器的一部分,它应该调度一些其他子进程。
因为我想等待一些进程完成,而不必等待其他进程完成,所以对于第二类进程,我使用双重fork(从而避免僵尸进程)。
问题是,我的服务器占用了很多内存,因此forking需要很长时间(即使在Linux中使用的仅复制页面表的写时复制fork)
我想用vfork()替换fork(),对于第二个fork很容易(因为它只在子进程中调用execve()),但我找不到任何方法可以替换第一个fork。
有人知道我该怎么做吗?
谢谢!

服务器是C++编写的linux(RH5U4)。

5个回答

2
为什么不让新执行的进程自己再进行一次fork呢?这样只有一个小而简单的进程需要复制其页表。
编辑:
当然,父进程必须进行短暂的wait()来清除那个僵尸进程,但是孙子进程可以运行任意长时间。

1

vfork() 只能用于 fork 然后调用 execexit。此外,vfork() 会阻塞父进程,直到子进程调用 _exitexec,这几乎肯定不是您想要的行为。

原因在于 vfork() 不会复制任何数据,包括堆栈,给新进程。所以一切都是共享的,很容易意外更改父进程无法处理的内容。由于数据是共享而没有副本,父进程不能同时继续运行,因此必须等待子进程调用 _exitexec,以便在父进程开始修改数据时不再使用它。


谢谢你,SoapBox。但我正在寻找一种解决方法,可以让我双重fork而不需要额外的fork()成本。 - Oren S
1
那是 _exit 而不是 exit。在 vfork 之后绝对不能调用 exit - R.. GitHub STOP HELPING ICE

1

我认为你真正想做的是利用SIGCHLD并维护一个子进程列表。这样,你就可以通过主进程被通知子进程状态变化(大多数情况下是它们死亡)并根据此执行一些操作来摆脱双重fork。你还可以跟踪任何超过预期完成时间的子进程(因为你在列表中存储了它们的创建时间),如果它们变得疯狂并且永远无法完成,则采取行动。


1

1

不要双重fork。 处理SIGCHLD以保存errno,调用wait,恢复errno。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接