What is the difference between fork()
and vfork()
? Does vfork()
return like fork()
.
相关问题
- Multiple sockets for clients to connect to
- What is the best way to do a search in a large fil
- glDrawElements only draws half a quad
- Index of single bit in long integer (in C) [duplic
- Equivalent of std::pair in C
Some systems have a system call vfork(), which was originally designed as a lower-overhead version of fork(). Since fork() involved copying the entire address space of the process, and was therefore quite expensive, the vfork() function was introduced (in 3.0BSD).
However, since vfork() was introduced, the implementation of fork() has improved drastically, most notably with the introduction of `copy-on-write', where the copying of the process address space is transparently faked by allowing both processes to refer to the same physical memory until either of them modify it. This largely removes the justification for vfork(); indeed, a large proportion of systems now lack the original functionality of vfork() completely. For compatibility, though, there may still be a vfork() call present, that simply calls fork() without attempting to emulate all of the vfork() semantics.
As a result, it is very unwise to actually make use of any of the differences between fork() and vfork(). Indeed, it is probably unwise to use vfork() at all, unless you know exactly why you want to.
The basic difference between the two is that when a new process is created with vfork(), the parent process is temporarily suspended, and the child process might borrow the parent's address space. This strange state of affairs continues until the child process either exits, or calls execve(), at which point the parent process continues.
This means that the child process of a vfork() must be careful to avoid unexpectedly modifying variables of the parent process. In particular, the child process must not return from the function containing the vfork() call, and it must not call exit() (if it needs to exit, it should use _exit(); actually, this is also true for the child of a normal fork()).
From my man page
Refer here and from wikipedia-
The intent of
vfork
was to eliminate the overhead of copying the whole process image if you only want to do anexec*
in the child. Becauseexec*
replaces the whole image of the child process, there is no point in copying the image of the parent.For other kinds of uses,
vfork
is dangerous and unpredictable.With most current kernels, however, including Linux, the primary benefit of
vfork
has disappeared because of the wayfork
is implemented. Rather than copying the whole image whenfork
is executed, copy-on-write techniques are used.The basic difference between the two is that when a new process is created with
vfork()
, the parent process is temporarily suspended, and the child process might borrow the parent's address space. This strange state of affairs continues until the child process either exits, or callsexecve()
, at which point the parent process continues.This means that the child process of a
vfork()
must be careful to avoid unexpectedly modifying variables of the parent process. In particular, the child process must not return from the function containing thevfork()
call, and it must not callexit()
(if it needs to exit, it should use_exit();
actually, this is also true for the child of a normalfork()
).However, since
vfork()
was introduced, the implementation offork()
has improved drastically, most notably with the introduction of 'copy-on-write', where the copying of the process address space is transparently faked by allowing both processes to refer to the same physical memory until either of them modify it. This largely removes the justification forvfork();
indeed, a large proportion of systems now lack the original functionality ofvfork()
completely. For compatibility, though, there may still be avfork()
call present, that simply callsfork()
without attempting to emulate all of thevfork()
semantics.As a result, it is very unwise to actually make use of any of the differences between
fork()
andvfork()
. Indeed, it is probably unwise to usevfork()
at all, unless you know exactly why you want to.As already stated, the
vfork
man page is clear about the differences. This topic gives a good description offork
,vfork
,clone
andexec
.Below are some often overlooked differences between
fork
andvfork
I experienced on some Linux 2.6.3x embedded systems I worked with.Even with copy-on-write techniques,
fork
fails if you don't have enough memory to duplicate the memory used by the parent process. For example, if the parent process uses 2 GB of resident memory (ie, memory that is used and not just allocated),fork
fails if you have less than 2 GB of free memory left. That's frustrating when you just want toexec
a simple program and therefore will never need that huge parent address space!vfork
doesn't have this memory issue, as it doesn't duplicate the parent address space. The child process acts more like a thread in which you are able to callexec*
or_exit
without hurting your parent process.Because memory page tables are not duplicated,
vfork
is much faster thanfork
andvfork
's execution time is not affected by the amount of memory the parent process uses, as pointed out here: http://blog.famzah.net/2009/11/20/fork-gets-slower-as-parent-process-use-more-memory/In situations where performance is critical and/or memory limited,
vfork
+exec*
can therefore be a good alternative tofork
+exec*
. The problem is that it is less safe and the man page saysvfork
is likely to become deprecated in the future.A safer and more portable solution may be to look at the
posix_spawn
function, which is higher level and offers more options. It safely usesvfork
when possible, depending on the options you pass it. I have been able to useposix_spawn
successfully and overcome that annoying "double memory checking issue" thatfork
+exec
was giving me.A really good page on this topic, with links to some
posix_spawn
examples.