我正在进行unix系统调用和进程控制。 我知道当调用vfork()时,给予子进程的控制以及子进程完成时,它调用_exit(),然后控件转到父进程。
问题1是:“我想把子进程带到执行,就在父进程之后”,,,有可能吗?
如果没有:如果是vfork(),父和子如何同时运行? 如果是:为什么我们需要使用vfork()(大多数功能与fork()相同)
问题2。我是否知道fork和vfork的进程结构,但无法捕获到哪里使用哪个?
请协助。
答案 0 :(得分:4)
问题2的简单答案是:始终使用fork
。切勿使用vfork
。
我不确定您提出的问题1. vfork
过程只能使用两个系统调用:_exit
和execve
。 (实际上,它可以使用exec
个系列中的任何一个,但execve
是最常见的。)一旦它执行了其中一个操作,它就会死亡(_exit
)或不再是vfork
(exec*
),不再阻止父级。因此,一旦孩子有了新的记忆图像,孩子和父母就可以共存。
在正常情况下,孩子将尝试呼叫execve
,除非失败,否则永远不会返回,然后立即呼叫_exit
,这只会在execve
失败时发生
孩子无法拨打dup
或close
,这通常是正确设置子流程所必需的。它不能修改任何内存(因为内存属于父内存。)因此它甚至很少有用。
曾几何时,流程创建很慢。现在,速度要快得多,而且大多数类Unix操作系统(包括Linux和FreeBSD)都使用“copy-on-write”,这大大降低了分叉子代的成本,后者不会修改内存(或修改很少的内存) 。因此,vfork
提供的限制和缺乏安全性不再有用。
vfork
已从2008版本的Posix中删除,应该被视为已弃用。
如果您确实发现fork
是性能问题,则应考虑使用posix_spawn
,如果它在您的系统上可用。 (据我所知,它可以在最新版本的Linux上使用,并且已经在FreeBSD和Solaris上使用了很长时间。)实际上可能会调用vfork
,但它至少会处理细节而不会导致在未定义的行为中。
答案 1 :(得分:2)
问题1是:“我想把子进程带到执行,就在父进程之后”
很明显,这不是vfork()
的用途。但是,这是系统调用的exec组(execl
,execv
等)所做的,除了子进程必须是独立的可执行文件。如果你只想要在另一件事之后发生一件事,你不需要fork或exec任何东西,只需按正确的顺序放置代码;)
问题2。我是否知道fork和vfork的进程结构,但无法捕获到哪里使用哪个?
vfork()
更专业,更受限制,因此通常使用fork()
。 linux vfork手册页提供了有关其使用价值的线索:
vfork()是clone(2)的一个特例。它用于创建新的 进程而不复制父进程的页表。的它 可能对孩子所在的性能敏感应用程序很有用 创建然后立即发出execve(2)。