fork()和vfork()有什么区别?vfork()是否像fork()一样返回。
发布于 2010-11-24 03:00:39
如果您只想在子进程中执行exec*,则vfork的目的是消除复制整个过程映像的开销。因为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 */
}对于其他类型的用途,vfork是危险和不可预测的。
然而,对于大多数当前的内核,包括Linux,由于fork的实现方式,vfork的主要好处已经消失了。使用写入时复制技术,而不是在执行fork时复制整个映像。
发布于 2011-03-06 09:04:39
如前所述,vfork手册页清楚地说明了其中的区别。此topic很好地描述了fork、vfork、clone和exec。
下面是我在使用过的一些Linux2.6.3x嵌入式系统上体验到的fork和vfork之间经常被忽略的一些区别。
即使使用写入时复制技术,如果没有足够的内存来复制父进程使用的内存,fork也会失败。例如,如果父进程使用2 GB的驻留内存(即已使用的内存,而不仅仅是分配的内存),那么如果剩余的空闲内存少于2 GB,fork就会失败。当您只想exec一个简单的程序,因此永远不会需要那么大的父地址空间时,这是令人沮丧的!
vfork没有这个内存问题,因为它不复制父地址空间。子进程的行为更像是一个线程,您可以在其中调用exec*或_exit,而不会损害父进程。
因为内存页表不是重复的,所以vfork比fork快得多,并且vfork的执行时间不受父进程使用的内存量的影响,如下所示:http://blog.famzah.net/2009/11/20/fork-gets-slower-as-parent-process-use-more-memory/
因此,在性能非常关键和/或内存有限的情况下,vfork + exec*可以很好地替代fork + exec*。问题是它不太安全,手册页上说vfork在未来可能会被弃用。
更安全和更可移植的解决方案可能是查看posix_spawn函数,该函数级别更高,提供了更多选项。它尽可能安全地使用vfork,这取决于您传递给它的选项。我已经能够成功地使用posix_spawn,并克服了fork + exec给我带来的恼人的“双重内存检查问题”。
A really good page on this topic, with links to some posix_spawn examples.
发布于 2010-11-24 02:52:24
从我的手册页
() vfork()函数与fork(2)具有相同的效果,不同之处在于,如果vfork()创建的进程修改用于存储vfork()返回值的pid_t类型变量以外的任何数据,或者从调用vfork()的函数返回,或者在成功调用_exit(2)或exec(3)系列函数之前调用任何其他函数,则行为未定义。
vfork()与fork(2)的不同之处在于,父进程被挂起,直到子进程终止(正常情况下,通过调用_exit(2)终止,或者在传递致命信号后异常终止),或者调用execve(2)。在此之前,子进程与父进程共享所有内存,包括堆栈。子对象不能从当前函数返回或调用exit(3),但可以调用_exit(2)。
https://stackoverflow.com/questions/4259629
复制相似问题