fork()和vfork()有什么区别?

use*_*401 32 c unix fork vfork

fork()和之间有什么区别vfork()?是否vfork()返回喜欢fork().

Bla*_*iev 36

目的vfork是消除复制整个过程图像的开销,如果你只想exec*在孩子中做一个.因为exec*替换子进程的整个图像,所以没有必要复制父进程的图像.

if ((pid = vfork()) == 0) {
  execl(..., NULL); /* after a successful execl the parent should be resumed */
  _exit(127); /* terminate the child in case execl fails */
}
Run Code Online (Sandbox Code Playgroud)

对于其他类型的用途,vfork是危险的和不可预测的.

然而,对于大多数当前的内核,包括Linux,vfork由于实现的方式,主要的好处已经消失fork.不是在fork执行时复制整个图像,而是使用写时复制技术.

  • Linux也有一个真正的`vfork(2)`.一般来说,我猜每个移植到非MMU平台的*nix都有一个真正的`vfork(2)`. (7认同)
  • 基于BSD的系统仍具有真正的*vfork*功能.阅读来源. (2认同)
  • 重要的是要注意*写时复制技术*.仅当新进程尝试修改内存时才会复制内存.对Android这样的系统非常关键. (2认同)

dco*_*coz 23

如前所述,vfork手册页清楚地表明了差异.这个话题给出了一个很好的说明fork,vfork,cloneexec.

下面是一些与经常被忽视的差异forkvfork我经历了一些Linux 2.6.3x嵌入式系统和我一起工作.

即使使用写时复制技术,fork如果没有足够的内存来复制父进程使用的内存,也会失败.例如,如果父进程使用2 GB驻留内存(即,使用的内存而不仅仅是已分配的内存),fork如果剩余的可用内存少于2 GB,则会失败.当你只想要exec一个简单的程序时,这是令人沮丧的,因此永远不需要那么大的父地址空间!

vfork没有此内存问题,因为它不会复制父地址空间.子进程更像是一个线程,您可以在其中调用exec*_exit不会损害您的父进程.

因为内存页表不重复,vfork所以比执行时间快得多,fork并且vfork执行时间不受父进程使用的内存量的影响,如下所示:http://blog.famzah.net/2009/11/20 /叉得到-慢作为父进程使用-更多存储器/

在性能至关重要和/或内存有限的情况下,vfork+ exec*因此可以是fork+ 的良好替代exec*.问题是它不太安全,并且手册页说明vfork将来可能会被弃用.

更安全,更便携的解决方案可能是查看posix_spawn更高级别的功能并提供更多选项.它会vfork尽可能安全地使用,具体取决于您传递的选项.我已经能够使用posix_spawn成功,克服恼人的"双内存检查问题"这fork+ exec是给我.

关于这个主题的一个非常好的页面,包含一些posix_spawn示例的链接.

  • 顺便说一句,Java的`的Runtime.exec()`历来使用`叉()/执行exec()`,但IIRC的Java 1.7将使用'的vfork()/执行exec()`或`的posix_spawn()`(如有). (2认同)