The difference between fork(), vfork(), exec() and clone()
fork()
- creates a new child process, which is a complete copy of the parent process. Child and parent processes use different virtual address spaces, which is initially populated by the same memory pages. Then, as both processes are executed, the virtual address spaces begin to differ more and more, because the operating system performs a lazy copying of memory pages that are being written by either of these two processes and assigns an independent copies of the modified pages of memory for each process. This technique is called Copy-On-Write (COW).vfork()
- creates a new child process, which is a "quick" copy of the parent process. In contrast to the system callfork()
, child and parent processes share the same virtual address space. NOTE! Using the same virtual address space, both the parent and child use the same stack, the stack pointer and the instruction pointer, as in the case of the classicfork()
! To prevent unwanted interference between parent and child, which use the same stack, execution of the parent process is frozen until the child will call eitherexec()
(create a new virtual address space and a transition to a different stack) or_exit()
(termination of the process execution).vfork()
is the optimization offork()
for "fork-and-exec" model. It can be performed 4-5 times faster than thefork()
, because unlike thefork()
(even with COW kept in the mind), implementation ofvfork()
system call does not include the creation of a new address space (the allocation and setting up of new page directories).clone()
- creates a new child process. Various parameters of this system call, specify which parts of the parent process must be copied into the child process and which parts will be shared between them. As a result, this system call can be used to create all kinds of execution entities, starting from threads and finishing by completely independent processes. In fact,clone()
system call is the base which is used for the implementation ofpthread_create()
and all the family of thefork()
system calls.exec()
- resets all the memory of the process, loads and parses specified executable binary, sets up new stack and passes control to the entry point of the loaded executable. This system call never return control to the caller and serves for loading of a new program to the already existing process. This system call withfork()
system call together form a classical UNIX process management model called "fork-and-exec".
vfork()
is an obsolete optimization. Before good memory management,fork()
made a full copy of the parent's memory, so it was pretty expensive. since in many cases afork()
was followed byexec()
, which discards the current memory map and creates a new one, it was a needless expense. Nowadays,fork()
doesn't copy the memory; it's simply set as "copy on write", sofork()
+exec()
is just as efficient asvfork()
+exec()
.clone()
is the syscall used byfork()
. with some parameters, it creates a new process, with others, it creates a thread. the difference between them is just which data structures (memory space, processor state, stack, PID, open files, etc) are shared or not.
execve()
replaces the current executable image with another one loaded from an executable file.fork()
creates a child process.vfork()
is a historical optimized version offork()
, meant to be used whenexecve()
is called directly afterfork()
. It turned out to work well in non-MMU systems (wherefork()
cannot work in an efficient manner) and whenfork()
ing processes with a huge memory footprint to run some small program (think Java'sRuntime.exec()
). POSIX has standardized theposix_spawn()
to replace these latter two more modern uses ofvfork()
.posix_spawn()
does the equivalent of afork()/execve()
, and also allows some fd juggling in between. It's supposed to replacefork()/execve()
, mainly for non-MMU platforms.pthread_create()
creates a new thread.clone()
is a Linux-specific call, which can be used to implement anything fromfork()
topthread_create()
. It gives a lot of control. Inspired onrfork()
.rfork()
is a Plan-9 specific call. It's supposed to be a generic call, allowing several degrees of sharing, between full processes and threads.