Anything. It's just an outdated concept, for the sake of ongoing compatibility. Single Unix Specification
says the following:
There are two reasons why POSIX programmers call fork(). One reason is to create a new thread of control within the same program (which was originally only possible in POSIX by creating a new process); the other is to create a new process running a different program. In the latter case, the call to fork() is soon followed by a call to one of the exec functions.
That is, literally, fork-and there are two applications: the creation of a new process from the new binary and creating a new "stream" in the framework of the current process. In both cases, it has drawbacks originating from the fork-a:
1) When you create a process first copied the address space (not memory, namely address space — each process it in any case), the descriptors and other resources, to immediately to liberate them (this problem is partially solved vfork)
2) When a thread is created again, the address space is copied instead of performing the same.
Comes to my mind the only use that could be useful: create a sandbox a-la Chrome/IE7. The creation of a new process by copying old will be on a few million (a few milliseconds on modern processors) clock cycles cheaper — for those who are important to the creation of sandboxes in large quantities (and for some reason "prefork" pool of such sandboxes are not suitable) it could be significant.
There is another problem in addition to relatively small performance degradation in the two most frequently used scenarios. Here is how the problem is still the same SUS:
The general problem with making fork() work in a multi-threaded world is what to do with all of the threads. There are two alternatives. One is to copy all of the threads into the new process. This causes the programmer or implementation to deal with threads that are suspended on system calls or that might be about to execute system calls that should not be executed in the new process. The other alternative is to copy only the thread that calls fork(). This creates the difficulty that the state of process-local resources is usually held in process memory. If a thread that is not calling fork() holds a resource, that resource is never released in the child process because the thread whose job it is to release the resource does not exist in the child process.
In modern design there is quite an important concept of connectedness
. So, a traditional UNIX process has a low connectivity. It is both a container of resources (by simplifying, we can say that it is an abstraction of memory) and the unit of execution (an abstraction of the CPU).
Posix thread-s are designed to solve this problem, but they are incompatible with fork. So it is better to use the approach described in the same SUS:
When a programmer is writing a multi-threaded program, the first described use of fork(), creating new threads in the same program, is provided by the pthread_create() function. The fork() function is thus used only to run new programs, and the effects of calling functions that require certain resources between the call to fork() and the call to an exec function are undefined.
Use a fork ONLY to run new programs, for everything else use pthread_create.