CONCEPT Cited by 1 source
fork() and execve()¶
Definition¶
fork() and execve() are the two POSIX system calls that
together create and initialise new processes
on Unix-family operating systems. fork() duplicates the calling
process; execve() replaces the current process's program image
with a new one loaded from disk. On Linux, both (along with
pthread_create() for threads) are
implemented as thin wrappers around a single unified
clone() system call with different flag combinations.
fork() — process duplication¶
fork() creates an exact clone of the calling process — same
code, same memory contents (copy-on-write in modern kernels), same
open file descriptors. After the call:
- The parent process continues execution with
fork()'s return value = child PID. - The child process begins execution with
fork()'s return value = 0.
Both processes continue from the same instruction pointer. The canonical branching idiom:
pid_t pid = fork();
if (pid == 0) {
// child path
} else if (pid > 0) {
// parent path
} else {
// fork failed
}
execve() — program replacement¶
execve(path, argv, envp) replaces the calling process's program
image (code, heap, stack) with a new one loaded from path,
preserving the PID and inherited-but-open file descriptors. Unlike
fork(), execve() does not return on success — the new
program starts fresh at its entry point.
Canonical spawn-a-program pattern¶
fork + execve compose to run a new program without losing the
parent:
pid_t pid = fork();
if (pid == 0) {
execve("/usr/bin/ls", argv, envp);
// only reached if execve failed
_exit(1);
}
// parent continues, can wait(2) for child
This two-step decomposition is the reason Unix shells can do
things like redirect I/O: between fork() and execve() in the
child, the shell can dup2() the child's stdin/stdout/stderr to
different file descriptors that the subsequent execve() inherits.
clone() — the unified substrate¶
On Linux, fork() and pthread_create() are both implemented as
calls to clone() with different flag combinations:
fork()equivalent:clone()with noCLONE_*flags → new address space + new thread.pthread_create()equivalent:clone(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM)→ new thread sharing the existing process's virtual memory, file descriptors, signal handlers, etc.
The relevant flags include CLONE_VM (share virtual memory —
creates a thread not a process), CLONE_FILES (share file
descriptors), CLONE_FS (share filesystem info), CLONE_SIGHAND
(share signal handlers), CLONE_PARENT (parent-of-caller semantics).
"Both fork() and pthread_create() are ultimately wrappers
around another system call: clone(). There are a number of flags
that you can pass to clone() to adjust its behavior for spawning
either a process or a thread." (Source: [[sources/2026-04-21-
planetscale-processes-and-threads]])
Process tree at boot¶
Every process on a running Unix system is a descendant of the
initial process created at boot (init or systemd on modern
Linux). There is exactly one root; every other process traces its
ancestry through fork() calls back to it.
Database architectural implication¶
Process-per-connection
databases like Postgres invoke fork()
(typically through a helper like PostMaster) on every new client
connection to spawn a dedicated backend. The fork cost itself is
small (copy-on-write page tables), but the per-backend steady-
state memory + scheduler bookkeeping (
context-switch tax) is what drives connection-pool adoption.
Seen in¶
- sources/2026-04-21-planetscale-processes-and-threads — Ben
Dicken canonicalises
fork()+execve()+clone()+pthread_create()at the pedagogy altitude with made-up simulator instructions (FORK,EXEC,PTCREATE). Includes the canonical boot-descendant framing: "When a computer boots up, a single process is initiated and all others are descendants of this one."
Related¶
- concepts/process-os — the abstraction these calls create.
- concepts/thread-os — the lighter variant via
pthread_create/clone(CLONE_VM). - concepts/context-switch — what the OS does between the running processes this creates.
- patterns/process-per-connection-database — Postgres's model,
invokes
fork()per client.
References¶
man 2 fork,man 2 execve,man 2 clone,man 3 pthread_createfor the canonical Linux/POSIX specifications.