srg@quick.COM (Spencer Garrett) (09/28/87)
In article <7672@felix.UUCP>, preston@felix.UUCP (Preston Bannister) writes: } In article <838@usfvax2.UUCP> chips@usfvax2.UUCP (Chip Salzenberg) writes: } } >There is one thing about UNIX fork()-exec() that you've overlooked -- } >after the fork(), the child process can set up the environment of the } >soon-to-be-exec'ed process by modifying its own environment. } >(Can you say `pipes, I/O redirection and current directory'? } >I knew you could.) } } What I should have said :-) was that the } code executed between the fork() and exec() call typically does not } need the full semantics of fork(). Indeed it does not. That's why Berkeley has vfork(). A vfork call "borrows" the parent's memory instead of copying it. The parent is kept in suspended animation while the child modifies the new environment. When the child exec's (or exit's) the memory is given back to the parent instead of being freed.
kent@tifsie.UUCP (Russell Kent) (09/30/87)
in article <125@quick.COM>, srg@quick.COM (Spencer Garrett) says: > Xref: tifsil comp.arch:734 comp.unix.wizards:1187 comp.os.minix:494 > > In article <7672@felix.UUCP>, preston@felix.UUCP (Preston Bannister) writes: > } What I should have said :-) was that the > } code executed between the fork() and exec() call typically does not > } need the full semantics of fork(). > > Indeed it does not. That's why Berkeley has vfork(). A vfork call > "borrows" the parent's memory instead of copying it. This (perhaps unfortunately) includes the information about open FILEs and file descriptors, which precludes the redirection of the child's streams without a good deal of work by the parent to recover. Preston's objections to the fork()/exec() concepts are valid; they glob together concepts which should have been kept separate. Unfortunately, the inertia of all those programs running already will probably preclude us from re-defining the process startup primitives. An alternative solution to the problem of poor performance during the fork() is to use a copy-on-write algorithm which gradually duplicates the parent's address space as the parent or child attempts to change values. (Can you say real MMU? :-) -- Russell Kent Phone: +1 214 995 3501 Texas Instruments - MS 3635 Net mail: P.O. Box 655012 ...!{ihnp4,uiucdcs}!convex!smu!tifsie!kent Dallas, TX 75265 ...!ut-sally!im4u!ti-csl!tifsie!kent
chris@mimsy.UUCP (10/04/87)
In some article (the quoting was improper, and I have forgotten who) someone writes: >>... That's why Berkeley has vfork(). A vfork call >>"borrows" the parent's memory instead of copying it. In article <246@tifsie.UUCP> kent@tifsie.UUCP (Russell Kent) replies: >This (perhaps unfortunately) includes the information about open FILEs and >file descriptors, which precludes the redirection of the child's streams >without a good deal of work by the parent to recover. Not so. Were this the case, vfork() would be nearly useless. Vfork borrows the parent's *memory*; this does not include its kernel space information, such as file descriptors. (`FILE *'s are indeed borrowed; the child is simply not supposed to muck about with them.) >... An alternative solution to the problem of poor performance during >the fork() is to use a copy-on-write algorithm which gradually duplicates >the parent's address space as the parent or child attempts to change >values. The standard objection to this is that the parent is likely immediately to change some values, and that it may be cheaper to duplicate the entire process once than to do it piecemeal. A standard solution is for the child to `borrow' the parent's memory (read only) until it exec()s or some short time has passed, after which the parent is allowed to continue regardless. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
richard@aiva.ed.ac.uk (Richard Tobin) (10/16/87)
In article <8904@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: >Vfork borrows the parent's *memory*; this does not include its >kernel space information, such as file descriptors. (`FILE *'s >are indeed borrowed; the child is simply not supposed to muck about >with them.) Indeed, it would usually be pointless to muck about with them, because they're going to disappear when the child execs another program. The things that are shared between the parent and child are just the things that don't survive an exec. -- Richard Tobin, JANET: R.Tobin@uk.ac.ed AI Applications Institute, ARPA: R.Tobin%uk.ac.ed@nss.cs.ucl.ac.uk Edinburgh University. UUCP: ...!ukc!ed.ac.uk!R.Tobin
mouse@mcgill-vision.UUCP (der Mouse) (11/18/87)
In article <179@aiva.ed.ac.uk>, richard@aiva.ed.ac.uk (Richard Tobin) writes: > In article <8904@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: >> Vfork borrows the parent's *memory*; this does not include its >> kernel space information, such as file descriptors. True, though file descriptors are a bad example - the child gets clones of the parent's file descriptors with vfork() just as it does with fork(). > Indeed, it would usually be pointless to muck about with [the > parent's stdio streams], because they're going to disappear when the > child execs another program. The things that are shared between the > parent and child are just the things that don't survive an exec. In fact, this is the whole point of vfork() - share the things that can be given back on exec(). However, it is not quite "pointless" to mess with stdio streams. Consider the following program: main() { printf("xxx"); if (vfork() == 0) { printf("yyy"); exec(....); _exit(1); } printf("zzz\n"); } (note the lack of fflush()es). This will print xxxyyyzzz\n, for the printf in the child is merely buffered - and the buffer is shared. If we add fflush(stdout); after printf("yyy"); then we get xxxyyyzzz\n as before, though for different reasons: the child's fflush empties the stdio buffer, which remains emptied when the parent gets the memory back. Of course, it *is* a bad idea for the child to mess around with anything the parent owns (such as is done in the above code), because code depending on the sharing semantics will break when someone finally fixes fork() to do a proper copy-on-write fork, and thus eliminates the need for vfork() and makes it equivalent to fork(). der Mouse (mouse@mcgill-vision.uucp)
mash@mips.UUCP (John Mashey) (11/24/87)
In article <909@mcgill-vision.UUCP> mouse@mcgill-vision.UUCP (der Mouse) writes: ... >code depending on the sharing semantics will break when someone finally >fixes fork() to do a proper copy-on-write fork, Many UNIXes, including SVR3 already do copy-on-write forks. -- -john mashey DISCLAIMER: <generic disclaimer, I speak for me only, etc> UUCP: {ames,decwrl,prls,pyramid}!mips!mash OR mash@mips.com DDD: 408-991-0253 or 408-720-1700, x253 USPS: MIPS Computer Systems, 930 E. Arques, Sunnyvale, CA 94086
berke@acf8.UUCP (Wayne Berke) (11/27/87)
> main() > { > printf("xxx"); > if (vfork() == 0) > { printf("yyy"); > exec(....); > _exit(1); > } > printf("zzz\n"); > } > > (note the lack of fflush()es). This will print xxxyyyzzz\n, for the It could also print "xxxzzz\nyyy". You're dealing with a parallel program here! Wayne Berke (berke@nyu.edu)
berke@acf8.UUCP (Wayne Berke) (11/28/87)
Re: my earlier posting. Woops. I didn't know that vfork caused an implicit wait() in the parent. Thus the original program was NOT parallel. My thanks to those who corrected me. Wayne Berke