Why is the default process creation mechanism fork?

6,567

Solution 1

It's to simplify the interface. The alternative to fork and exec would be something like Windows' CreateProcess function. Notice how many parameters CreateProcess has, and many of them are structs with even more parameters. This is because everything you might want to control about the new process has to be passed to CreateProcess. In fact, CreateProcess doesn't have enough parameters, so Microsoft had to add CreateProcessAsUser and CreateProcessWithLogonW.

With the fork/exec model, you don't need all those parameters. Instead, certain attributes of the process are preserved across exec. This allows you to fork, then change whatever process attributes you want (using the same functions you'd use normally), and then exec. In Linux, fork has no parameters, and execve has only 3: the program to run, the command line to give it, and its environment. (There are other exec functions, but they're just wrappers around execve provided by the C library to simplify common use cases.)

If you want to start a process with a different current directory: fork, chdir, exec.

If you want to redirect stdin/stdout: fork, close/open files, exec.

If you want to switch users: fork, setuid, exec.

All these things can be combined as needed. If somebody comes up with a new kind of process attribute, you don't have to change fork and exec.

As larsks mentioned, most modern Unixes use copy-on-write, so fork doesn't involve significant overhead.

Solution 2

In adition to the cjm's answer, the Single Unix Specification defines a function named vfork(). That function works like fork, except that the forked process has undefined behavior if it does anything other than try calling an exec familly function, or calling _exit().

Thus pretty much the only use with defined behavior is:

pid_t ret = vfork();
if(ret == 0)
{
    exec(...);
    _exit(EXIT_FAILURE); //in case exec failed for any reason.
}

So what does vfork do? It is is an inexpensive fork. In implemenations without copy-on-write, the resulting process will share memory space with the original process (hence the undefined behavior). In implementations with copy-on-write, vfork is permitted to be identical to fork(), since copy-on-write implementations are fast.

There is also the optional posix_spawn function (and a posix_spawnp function) which can directly create a new process. (It is also permissible to implement them with a library call using fork and exec, and an example implementation is provided.)

Share:
6,567

Related videos on Youtube

Ellen Spertus
Author by

Ellen Spertus

I am a computer science professor at Mills College. I used to work at Google on projects such as App Inventor (which I still contribute to), Blockly, and the Hour of Code. I have done research in computer architecture, compilers, artificial intelligence, information retrieval, and data mining.

Updated on September 18, 2022

Comments

  • Ellen Spertus
    Ellen Spertus over 1 year

    The UNIX system call for process creation, fork(), creates a child process by copying the parent process. My understanding is that this is almost always followed by a call to exec() to replace the child process' memory space (including text segment). Copying the parent's memory space in fork() always seemed wasteful to me (although I realize the waste can be minimized by making the memory segments copy-on-write so only pointers are copied). Anyway, does anyone know why this duplication approach is required for process creation?

  • Admin
    Admin over 12 years
    In fact, don't honest comparisons of fork vs CreateThread usually show that fork is competitive with CreateThread?
  • Kyle Jones
    Kyle Jones over 12 years
    Excellent explanation. "Those who don't understand UNIX are condemned to reinvent it, poorly." -- Henry Spencer
  • Ellen Spertus
    Ellen Spertus over 12 years
    Thanks! Do you have a reference, by any chance?
  • Aki
    Aki over 12 years
    I believe windows uses a "fork" system call in the end... However this is so low level that it is probably not officially documented. Windows likes cOOLaPIfUnctions that abstract its internals (which is relatively useful to the bad guys evading antivirus and such).
  • Steven Monday
    Steven Monday over 12 years
    But must there not be some equivalent of CreateProcess() somewhere in Unix? Otherwise how does the very first process get created? Unlike a mythological creator god, the first process cannot fork() itself from nothingness. ;-)
  • cjm
    cjm over 12 years
    @StevenMonday, yes, but it's in the kernel's initialization code and not externally accessible. It doesn't need all those parameters because almost everything is hardcoded. It can only create process ID 1, a.k.a. the init process. After that, processes are created only by forking.
  • psusi
    psusi over 12 years
    @StevenMonday, the first process is hand crafted by God ( the kernel )
  • MusiGenesis
    MusiGenesis over 12 years
    POSIX has in fact added a complex fork-and-exec combined interface in posix_spawn: pubs.opengroup.org/onlinepubs/009695399/functions/… Most software still uses the older, simpler interfaces though.
  • Olivier Dulac
    Olivier Dulac about 10 years
    I believe the "copy on write" feature is a good reason of the use of fork : by forking an existing process, you can start immediately the forked process if it's largely similar. Only the differing parts will be needed to be written to a different memory location, not the whole thing, if there are similitudes. (ex: a bash shell forking another to handle a pipe : most of everything is similar in both bash processes, so almost no need to copy anything to a new memory location for the 2nd process. Just duplicate memory pointers, no need to copy the program binary over. Hence it's VERY fast).
  • ctrl-alt-delor
    ctrl-alt-delor about 7 years
    @StevenMonday The first process could not CreateProcess it self, any more than it could fork it self. “In the beginning was Init, and Init was with the Kernel, and Init was the Kernel. It was with the Kernel in the beginning. Through It all things were forked; without It nothing was forked that has been forked. In It was life, and that life was the light of the whole operating system. The light shines in the darkness, and the darkness has not overcome it.”