mouse@mcgill-vision.UUCP (der Mouse) (06/27/87)
Quotes are from articles <21731@sun.uucp> and <21685@sun.uucp>, written by guy%gorodish@Sun.COM (Guy Harris). > There is very little you can do with the (temporarily) shared memory > you get from "vfork", and in most, if not all, cases, you can do the > same thing just as well without it. Well, I wrote such code (just once, as far as I can recall). The child process had to do some fiddling before execing. It was possible for it to fail during this fiddling. Also, the parent had to know the exit code of the execed program, if it was really executed; this exit code could be any of the possible exit codes. How is the parent to know whether the child succeeded in its fiddling and exec? I used the `shared' memory to pass a flag back to the parent. This was simple, fast, and obvious (I noted the dependence on the (admittedly) ugly vfork() semantics in a comment at that point in the code). I see no way to pass this back without using a temporary file (ugh) or a pipe (double ugh; and is it guaranteed to have enough buffer capacity?). > The only remaining reason to use vfork is that one has written ugly > and brain-damaged code that depends on the semantics of "vfork". > [...] If anybody has written code of this sort, they should hang > their head in shame and then go out and fix it NOW. Well, I'm not exactly proud of the technique, but I won't go so far as to hang my head in shame. Fix it, you say; but what fix would you recommend I use? der Mouse (mouse@mcgill-vision.uucp)
guy%gorodish@Sun.COM (Guy Harris) (06/30/87)
> Well, I'm not exactly proud of the technique, but I won't go so far as > to hang my head in shame. Fix it, you say; but what fix would you > recommend I use? Well, first go read the "vfork" manual, paying special attention to the part that says "don't do that", and then change the process to send itself an unused signal (such as SIGUSR[12] on 4.3BSD) if the "exec" fails. Unless somebody is being perverse and randomly sending unused signals around, which is extremely unlikely (and anybody who does that gets what they deserve anyway), the fact that the child was terminated by this signal indicates that the "exec" fails. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
gwyn@smoke.BRL.MIL (Doug Gwyn) (06/19/89)
In article <1989Jun19.013230.16107@marob.masa.com> daveh@marob.masa.com (Dave Hammond) writes: >Can someone provide concrete examples of where I'd want to use vfork(), >rather than fork()? Don't use vfork(). It can cause problems for the unwary, it doesn't exist on non-BSD operating systems, and even Berkeley has threatened to remove support for it (in which case it will probably become an alias for fork()).
guy@auspex.auspex.com (Guy Harris) (06/29/89)
>From what I can glean from the manual, the advantages of vfork() over >fork() are (1) virtual memory efficiency and (2) shared access to parent >memory, data structures, etc. until an execv(). The Berkeley VFORK(2) manual page quite specifically states that 2) is NOT to be depended on as a "feature" of "vfork()": BUGS This system call will be eliminated when proper system sharing mechanisms are implemented. Users should not depend on the memory sharing semantics of "vfork" as it will, in that case, be made synonymous to "fork".
mats@oblio.UUCP (Mats Wichmann) (06/30/89)
daveh@marob.masa.com (Dave Hammond) writes: >Can someone provide concrete examples of where I'd want to use vfork(), >rather than fork()? When you know you are going to do an exec() right away. Which the Berkeley people argue (correctly) is a very frequent use for fork(). The issue is that copying the process space of the parent to make the child seems like a lot of work if you are going to throw it away by exec'ing another program right away. So vfork() shares the addresses spaces instead of making a copy. Making the child copy-on-write is another way to accomplish this (transparently), as in Sys V.3, but there you still pay the costs to set up the table structures. Another way is to get real virtual memory (Mach claims to do this stuff better, for example). Mats Wichmann Acer America
daveh@marob.masa.com (Dave Hammond) (07/22/89)
Pertaining to vfork() and fork() usage in Berkely-specific C programs: From what I can glean from the manual, the advantages of vfork() over fork() are (1) virtual memory efficiency and (2) shared access to parent memory, data structures, etc. until an execv(). The disadvantage seems to be that returning to the parent context while the childs context still exists does not work. Does this mean that spawning an asynchronous process via vfork() is not possible? My application wants to spawn children to: (1) execute adhoc subtasks (like `system("command")' ). (2) execute adhoc subtasks asynchronously (like `system("command &")' ). (3) execute cooperative subtasks for data sharing (like `popen("command")' ). My feeling is that vfork() is less appropo for this application than fork(). Am I offbase about this? Can someone provide concrete examples of where I'd want to use vfork(), rather than fork()? -- Dave Hammond daveh@marob.masa.com
guy@auspex.auspex.com (Guy Harris) (08/18/89)
>Pertaining to vfork() and fork() usage in Berkely-specific C programs: > >From what I can glean from the manual, the advantages of vfork() over >fork() are (1) virtual memory efficiency and (2) shared access to parent >memory, data structures, etc. until an execv(). Uhh, 2) isn't supposed to be thought of as an advantage - it's supposed to be thought of as a consequence of the current implementation, subject to change at any time. I.e., don't *rely* on this behavior, for, as the vfork man page says: BUGS This system call will be eliminated when proper system sharing mechanisms are implemented. Users should not depend on the memory sharing semantics of "vfork" as it will, in that case, be made synonymous to "fork". >The disadvantage seems to be that returning to the parent context while >the childs context still exists does not work. Does this mean that >spawning an asynchronous process via vfork() is not possible? Unless the asynchronous process is going to be running a different program - i.e., it's going to do an "exec" - yes. "vfork" was specifically intended to be used when the subprocess was going to do a few things - things like shuffle file descriptors, change current directory, etc. - and then "exec". None of those things should modify any global data structures whatsoever, except for those in the kernel/U area.... >My application wants to spawn children to: >(1) execute adhoc subtasks (like `system("command")' ). >(2) execute adhoc subtasks asynchronously (like `system("command &")' ). >(3) execute cooperative subtasks for data sharing (like `popen("command")' ). > >My feeling is that vfork() is less appropo for this application than >fork(). Am I offbase about this? If in the "like ..." examples you mean the child process really will do the equivalent of that - which means doing an "exec" of the program in question - "vfork()" is appropriate. If you mean that the child will be running the *same* code as the parent - and not simply by virtue of doing an "exec" of the same program - "vfork()" is completely inappropriate. >Can someone provide concrete examples of where I'd want to use vfork(), >rather than fork()? 1) The "system()" library routine could use it, since it just "exec"s "/bin/sh" after the "vfork()". (In fact, in 4.xBSD, it *does* use "vfork()".) 2) The "popen()" library routine could use it, since it just shuffles file descriptors and "exec"s "/bin/sh". (In fact, in 4.xBSD, it *does* use "vfork()".) 3) Shells can often use it, since they shuffle file descriptors, etc. and then "exec" the command. If the command is a script in their own language, though, and they're going to execute the script by e.g. jumping back to their main command-interpretation loop (which is basically what the Bourne shell does if the "exec" fails with ENOEXEC - if the file has a "#!" line, the "exec" succeeds because it fires up a new "/bin/sh"), they can't use it, though, since the child process will still be running the same program. 4) "make" can use it, since it just "exec"s the program or "/bin/sh". 5) Etc..
klee@gilroy.pa.dec.com (Ken Lee) (08/18/89)
In article <1989Jun19.013230.16107@marob.masa.com>, daveh@marob.masa.com (Dave Hammond) writes: > Can someone provide concrete examples of where I'd want to use vfork(), > rather than fork()? vfork is intended specifically for the case where the child process will exec soon after the vfork. The parent process is suspended in the interim. A quick exec is common (most of the time), so this performance hack is useful. In their book, Leffler, et al, say: "Although allowing modification of the parent's address space is bad programming practice, some programs have been known to take advantage of this quirk." You can play games with the parent during a vfork, but this is rarely worthwhile. Ken Lee DEC Western Software Laboratory, Palo Alto, Calif. Internet: klee@decwrl.dec.com uucp: uunet!decwrl!klee
dwc@cbnewsh.ATT.COM (Malaclypse the Elder) (08/18/89)
in unix system v release 4, fork will have all the advantages of vfork with none of the disadvantages (well almost). danny chen att!hocus!dwc
hutch@lzaz.ATT.COM (R.HUTCHISON) (08/22/89)
From article <3161@cbnewsh.ATT.COM>, by dwc@cbnewsh.ATT.COM (Malaclypse the Elder): > > in unix system v release 4, fork will have all the advantages > of vfork with none of the disadvantages (well almost). > > danny chen > att!hocus!dwc I think that SVR3 has these advantages already plus more. V.3 has copy-on-write (COW) pages, allowing parent and child to change the same image (by default). So, if the child does an exec() right away, the two are similar (in the amount of work the OS has to do). But... V.3 has extra goodies... 1) The SVR3 child does not have to obey the rules a vfork() child does - it can change the process image - whenever a change is made, the changing process (whomever it might be) gets its own copy of the page it changed - the rest remains shared. If a parent creates several children (through fork()s) they will all share the same image until one of them wants to change a page - then it will get its own copy and the rest will still share the original page. 2) Unrelated processes share data pages as well as (the traditional) text pages. This is great if you have large static tables - they are shared by all using the program. The same COW principle applies. Is there more that I'm missing? Bob Hutchison att!lzaz!hutch