vfork instead of fork for fork+exec?

Christos Zoulas christos at zoulas.com
Sat May 16 11:22:34 PDT 2009


On May 16, 10:48am, martinrb at google.com (Martin Buchholz) wrote:
-- Subject: Re: vfork instead of fork for fork+exec?

| On Sat, May 16, 2009 at 09:03, Christos Zoulas <christos at zoulas.com> wrote:=
| 
| > On May 16, =A05:12pm, dms at samersoff.net (Dmitry Samersoff) wrote:
| > -- Subject: Re: vfork instead of fork for fork+exec?
| >
| > | Charles,
| > |
| > | On BSD vfork() stops parent process until child exited or call exec.
| > | It's not acceptable in multithreaded environment.
| >
| > Yes, this could be a problem if the program does not run exec
| > immediately after vfork(), but in practice most programs run exec,
| > a couple of dups, and vfork because there is not much else you can
| > legally do without trashing the state of your parent.
| 
| The JDK needs to do the following after (v)fork():
| - close file descriptors
| - maybe chdir
| - maybe replace environ
| - communicate success/failure to parent
| 
|        The vfork() function has the same effect
|        as fork(2), except that the behavior is undefined if the  process  c=
| re-
|        ated  by vfork() either modifies any data other than a variable of t=
| ype
|        pid_t used to store the return value from vfork(), or returns from  =
| the
|        function  in  which  vfork()  was  called,  or calls any other funct=
| ion
|        before successfully calling _exit(2) or one of the  exec(3)  family =
|  of
|        functions.
| 

On BSD vfork() does not share file descriptors, current working
directory, and signals, and as the following program shows environment
too so all the items are fine (and it is trivial to write code that
proves this). If that was not the case (file descriptors were shared
for example), vfork() would be useless.  Even the shell does not
(because it cannot) use vfork() in every situation, but only when
it can. I don't know if it is worth the trouble of using vfork()
in java when it is possible, since fork() is not a very common
operation in java programs (I think).

christos


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

const char name[] = "FOO00BAR";

int
main(int argc, char *argv[])
{
	int status;

	switch (vfork()) {
	case -1:
		_exit(1);
	case 0:
		/*
		 * No need to wait here, we only get here if the child execed
		 * or exited
		 */
		printf(">%s\n", getenv(name));
		return 0;
	default:
		setenv(name, "vfork trashed me", 1);
		_exit(0);
	}
}



More information about the bsd-port-dev mailing list