由于vfork在与父节点相同的地址空间中创建子进程,并且在子节点上调用execv()时,父进程如何恢复,因为exec加载文件并在同一地址空间中运行它。父母,因此孩子?
当execv
遵循真正的vfork
时,它会完成fork
的一些工作:它会分配一个新的内存空间来加载新的程序映像并将可继承的东西(如环境变量)复制到其中。与此同时,甚至vfork
也会保留父母的一些状态,这样一旦孩子分开,execv
就可以恢复父母的堆栈和指令指针。
例如,在Linux上,vfork
通过_do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, ...)
调用常见的进程复制代码。 copy_mm
对CLONE_VM
作出反应,只是重新使用内存空间而没有调用dup_mm
。 _do_fork
同时对CLONE_VFORK
做出反应,标记了孩子vfork_done
,并暂停了来电者,直到记忆空间不再使用;如果这是通过execve
,它通过exec_mmap
和mm_release
,它看到vfork_done
并唤醒父母。
所以,真的,execve
(也称为copy_strings
)总是“分配一个新的内存空间并将环境变量复制到其中”;然而,在正常的fork
之后,这是不可观察的,因为它发生在释放由fork
创建的非共享空间的同时。