Simplified - C & Linux - Fork & Exec
Processes (Background)
Processes are basically a program which was executed. You double clicked an icon on your desktop? You probably initiated a process. On the develop'ish side of things, we can go deeper into how processes are created and ran.
On Unix-like systems, every process is created and executed by an already running process. The already running process is called the parent, and the created one is his child. These parent-child relations all form a processes tree (type ptree
in your terminal for an example). In case you wondered, the first parent is called 'Init' and it's a process that automatically runs on system launch.
Fork & Exec
The C function which creates a new process from a running one, is called fork()
. From the line that this function is called, there are 2 running processes of your code, as if you ran the executable twice. Luckily, fork
's return value is different for each of the processes, allowing us to conditionalize our code execution for each of them. It returns 0 in the child process, and a PID (process ID number) of the child, in the parent process. A simple example:
pid_t child_pid = fork();
if (0 == child_pid)
{
printf("This will be printed by the child process only!\n");
}
else
{
printf("This will be printed by the parent process only!\n");
}
note: fork
's failure case was discarded for simplicity. Fitting behavior for failure (-1 == child_pid
) should be added.
So fork
runs a copy of the current process from the line it's called. But what if you want to run a new process? That's what exec
is here for. exec
is a big family of functions which replaces the current process with a new one. Essentially, we can create a copy of the current process with fork
, and then transform it into a new, unrelated process with exec
!.
pid_t child_pid = fork();
if (0 == child_pid)
{
printf("This is the child process. We will now make it into a new one!\n");
execvp(file_name, args_for_it);
printf("This line will never be printed, unless execvp failed!\n");
}
else
{
printf("This is the parent process, it will keep running on the current
code file.\n");
}
In the example above, we used the function execvp
. You can read further about it's arguments online (or in the good ol' man
), but it's overall purpose is just as described above. The second printf
line won't be printed since once execvp
was called, the child process is no longer a copy of it's parent, but a new running process of whichever file we gave it!
Hope you got the simplified basics down! You should be ready to dive deeper into it as necessary.
RwK
Subscribe to my newsletter
Read articles from Roee Kishon directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Roee Kishon
Roee Kishon
A Software Developer coming from a scientific background (B.Sc. Molecular Biology). Blogging progress/learning as a self-tracking method.