Brain Dump

Fork

Tags
comp-arch

Is a system-call that clones the current process to create a new-process, duplicating the state of the existing process with a few minor differences. See fork.

Both the child and current process executes the line after the fork, just like the parent. The return value of fork is -1 if it failed, 0 when in the child process and the PID of the child-process when in the parent. The child can later access its parents PID using getppid, however the only way for a parent to know its child's PID is to store the output of fork. Put another way a process can have an arbitrary number of child processes, but only one parent. Therefore there's no method to access a list of all the child processes but there is one to access the parent process PID.

int out = fork();

if (out < 0) {
    printf("Failed to fork\n");
} else if (out == 0) {
    printf("Hi from the child process. I don't know my parents PID.\n");
} else {
    printf("Hi I'm the parent, I made a child process with id: %d.\n", out);
    waitpid(out); // Wait for the child to exit before continuing the parent.
}

Note: As a mild, but great, performance improvement the Linux kernel uses copy-on-write behaviour with the address space of forked processes. This means that both processes reference the same address space except when a variable is modified, in which case the data is allocated, copied over, and then modified. As a consequence of this read-only memory is always shared between forked processes.

Fork and FILEs

When a process is forked any open file descriptors are cloned, however the underlying file descriptions are not. This means:

  • If a child closes a file-descriptor inherited from its parent, the parents file descriptor remains open.
  • A call to read in the child process doesn't move the cursor along in the parent process.
int file = open(...);
if(!fork) {
    read(file, ...);
} else {
    read(file, ...);
}
Code Snippet 1: An example of fork where both the parent and child read different lines from the shared file description.
if(!fork) {
    int file = open(...);
    read(file, ...);
} else {
    int file = open(...);
    read(file, ...);
}
Code Snippet 2: An example of fork where the parent and child read the same lines from the same file because they each have their own file description.

Waiting on Child Processes

The wait and waitpid system-calls block the current thread until a process changes state (from/to one of the child terminated, the child was stopped by a signal or the child was resumed by a signal). Both of these functions take a pointer to an integer that it assigns to the exit-status of a process. The former does so for any child-process of the current process. The latter waits on a specific process instead.

You can use the WIFEXITED and the WEXITSTATUS functions to assert whether a process terminated normally and to parse out the exit code of the process.