A Fork in Your Code

All of the code I’ve written in my books as well as demonstrated on this blog has been single-tasking: The program runs as one process, does one thing, in order, and then terminates. With this Lesson, that streak ends.

Today’s operating systems handle multiple programs at once. They’re not called programs, but rather processes. So when you start some silly little C program you’ve written, it’s spawned as a new process in the system. The process is assigned a number or process ID (PID). It starts, runs, then stops. All the while other processes continue to run.

Spawning a new process inside a single program is the duty of the fork() function. That function is declared in the unistd.h header file. It returns a PID value representing a duplicate copy of the existing program call the child. The original code is called the parent.

When using the fork() function, it’s important to remember that the parent code is spawned as the child. So unlike the system() function, fork() doesn’t launch another program. Instead, you keep track of the two copies of the current code by using PID values.

Time for an example!

#include <stdio.h>
#include <unistd.h>

int main()
{
    fork();
    printf("This code's PID is %d\n",getpid());

    return(0);
}

Here’s sample output:

This code's PID is 59918
This code's PID is 59919

Despite only one printf() statement in the code, two lines are output. That’s because the fork() function spawned a child program, which ran its own printf() statement. The fork() function’s success is evident because the output shows two process ID values, parent and child. (Refer to last week’s Lesson for info on the getpid() function.)

Tracking PID values can be bothersome, so the fork() function assists you by returning different values, one for the parent process and another for the child. The parent process receives the value zero from the fork() function. The child process receives the parent’s process ID. You use these values to determine which process is running in your code.

Time for another example:

#include <stdio.h>
#include <unistd.h>

int main()
{
    pid_t pid;

    pid = fork();

    switch(pid)
    {
        case 0:
            printf("Parent PID: %d\n",getpid());
            printf("Parent fork() return value: %d\n",pid);
            break;
        default:
            printf("Child PID: %d\n",getpid());
            printf("Child fork() return value: %d\n",pid);
    }

    return(0);
}

Here’s the output on my machine:

Child PID: 59986
Child fork() return value: 59987
Parent PID: 59987
Parent fork() return value: 0

In the parent copy of the program, fork() returns 0. The parent’s PID is 59987.

The child copy receives the parent’s PID from the fork() function, 59987, but it has its own PID value, which is 59986, as shown above.

The order of output for the Child and Parent is unpredictable, given that you’re witnessing two programs running and both are using streamed output.

Once your code determines whether the child or parent is running, it can separate statements and functions to carry out multitasking. So the child part may dash off and run some function while the parent copy of the code does something else. Both processes happen simultaneously.

One thought on “A Fork in Your Code

Leave a Reply