HI
我正在编写服务器的一部分,该服务器应该调度其他一些子进程
因为我想等待一些进程,并在不等待完成的情况下派遣其他进程,我使用双叉进行第二种进程(从而避免了僵尸进程)。
问题是,我的服务器占用了大量内存,因此分叉需要很长时间(甚至在Linux中使用的只能复制分页表的copy-on-write fork)
我想用vfork()替换fork(),并且它很容易用于第二个fork(因为它只调用子进程中的execve()),但我找不到任何方法可以替换第一个。
有谁知道我怎么能这样做?
谢谢!
服务器是linux(RH5U4),用C ++编写。
答案 0 :(得分:2)
为什么不让新执行的进程自己做另一个fork呢?那样只有一个简单的小进程会复制其页表吗?
编辑:
当然,父母必须做一个短暂的等待()来清理那个僵尸,但是孙子进程可以运行它想要的时间。
答案 1 :(得分:1)
vfork()
只能用于分叉,然后拨打exec
或exit
。此外,vfork()
将阻止父进程,直到子进程调用_exit
或exec
,这几乎肯定不是您想要的行为。
原因是vfork()
不会为新进程制作任何数据的任何副本,包括堆栈。因此,所有内容都是共享的,并且很容易意外地更改父进程无法处理的内容。由于数据是在没有副本的情况下共享的,因此父进程无法与子进程同时继续运行,因此必须等待子进程_exit
或调用exec
以使其不再使用数据当父母开始修改它时。
答案 2 :(得分:1)
我认为您真正想要做的是使用SIGCHLD并维护子进程列表。然后,当孩子改变状态(大多数情况下,当他们死亡时)通知你的主要过程并且基于此对他们执行某些操作时,你可以取消双叉。您还可以跟踪您的任何子进程花费的时间超过预期(因为您将创建时间存储在列表中),并且如果它们发疯并且永远不会完成,请采取措施。
答案 3 :(得分:1)
不要双叉。处理SIGCHLD以保存错误,调用等待,恢复错误。
答案 4 :(得分:1)
我相信你可以使用我问的另一个问题的答案,出于类似的原因。您可以vfork()
+ exec()
添加到可再生的可执行文件。见setuid() before calling execv() in vfork() / clone()