Fundamentals 10 min read

Understanding Code, Programs, and Processes in Linux: Lifecycle, Fork, Exec, and Init

This article explains the differences between code, programs, and processes in Linux, demonstrates how to compile and run a simple program, explores parent‑child relationships, the role of the init process, the process lifecycle, and the copy‑on‑write mechanism.

Qunar Tech Salon
Qunar Tech Salon
Qunar Tech Salon
Understanding Code, Programs, and Processes in Linux: Lifecycle, Fork, Exec, and Init

A process is simply a running instance of a program; it is defined as a program in execution.

The concept of a process is fundamental to Linux, where processes can create, interrupt, and communicate with other processes.

Code VS Program VS Process

First, we distinguish code, program, and process.

Code example:

#include
#include
int main(void)
{
    printf("\n Hello World\n");
    sleep(10);
    return 0;
}

Saving this as helloWorld.c makes it a code file.

Program: compiling the code generates an executable:

$ gcc -Wall helloWorld.c -o helloWorld

The resulting helloWorld executable is the program.

Process: running the executable creates a process:

$ ./helloWorld

Hello World

The process executes all machine code of the program, making it the running instance of the program.

To inspect the newly created process, use ps :

$ ps -aef | grep hello*
1000      6163  3017  0 18:15 pts/0    00:00:00 ./helloWorld

Parent Process and Child Process

Every process has a parent process, though not every process has children.

Example ps output shows PID and PPID columns; the process with PID 6191 has PPID 3079, indicating that PID 3079 (a bash shell) is its parent.

When a process creates another via fork() , the creator is the parent and the new one is the child. Typically, a shell command invokes fork() followed by exec() .

If a parent process is killed while its child remains alive, the init process adopts the orphaned child.

Init Process

When Linux boots, the kernel loads vmlinuz , creating the first process: init . It has PID 1 and is the ancestor of all processes, the root of the process tree.

You can verify this with pstree :

init-+-NetworkManager-+-dhclient
   ...
   |-gnome-terminal-+-bash
   |                |-bash-+-less
   |                `-pstree
   ...

The output confirms init as the tree's head.

Process Lifecycle

The new process is created by fork() . If exec() follows, the process switches to kernel mode and gets a new address space.

During execution, a higher‑priority process may pre‑empt it, causing it to re‑enter the run queue.

A running process can enter kernel mode to access hardware or files, possibly sleeping until I/O completes, then being rescheduled.

Termination occurs via exit() , signal handling, or uncatchable signals. If the parent does not wait for the child, the child becomes a zombie until wait() / waitpid() is called.

Copy‑On‑Write

When duplicating an object, the system does not immediately copy memory; instead, it creates a pointer to the original and marks the page as copy‑on‑write. Reads use the shared page, while writes trigger an actual copy.

In Linux, after fork() (before exec() ), parent and child share the same physical memory for code, data, and stack. Only when either modifies a segment does the kernel allocate separate physical pages, preserving isolation while keeping the code segment shared until exec() replaces it.

Linuxprocesscopy-on-writeinitforkExec
Qunar Tech Salon
Written by

Qunar Tech Salon

Qunar Tech Salon is a learning and exchange platform for Qunar engineers and industry peers. We share cutting-edge technology trends and topics, providing a free platform for mid-to-senior technical professionals to exchange and learn.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.