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