10.8 Creating Clones
Although fork() is the traditional way of creating new processes in Unix, Linux also provides the clone() system call, which lets the process being duplicated specify what resources the parent process should share with its children.
int clone(int flags);
This is not much more than a fork(); the only difference is the flags parameter. It should be set to the signal that should be sent to the parent process when the child exits (usually, SIGCHLD), bitwise OR'ed with any number of the following flags, which are defined in <sched.h>:
CLONE_VM |
The two processes share their virtual memory space (including the stack). |
CLONE_FS |
File-system information (such as the current directory) is shared. |
CLONE_FILES |
Open files are shared. |
CLONE_SIGHAND |
The signal handlers are shared for the two processes. |
When two resources are shared, both processes see those resources identically. If the CLONE_SIGHAND is specified, when one of the processes changes the signal handler for a particular signal, both processes use the new handler (see Chapter 12 for details on signal handlers). When CLONE_FILES is used, not only is the set of open files shared, but the current location in each file is also shared. The return values for clone() are the same as for fork().
If a signal other than SIGCHLD is specified to be delivered to the parent on the death of a child process, the wait() family of functions will not, by default, return information on those processes. If you would like to get information on such processes, as well as on processes that use the normal SIGCHLD mechanism, the __WCLONE flag must be OR'ed with the flags parameter of the wait call. Although this behavior may seem odd, it allows greater flexibility. If wait() returned information on cloned processes, it would be more difficult to build standard thread libraries around clone(), because wait() would return information on other threads, as well as child processes.
Although it is not recommended that applications use clone() directly, numerous user-space libraries are available that use clone() and provide a fully POSIX-compatible thread implementation. The glibc library includes libpthread, which provides the most popular thread implementation. Several good books on POSIX thread programming are available [Butenhof, 1997] [Nichols, 1996].