Overview
of 3
Level
What is a Process?
A process is simply a running instance of a program. When you type ./myprogram in a terminal, the operating system creates a process for it. That process gets its own memory, its own file descriptors, and its own CPU time. Process creation is how one running program starts another process.
Creating multiple processes is a powerful way to divide and conquer work. Common real-world examples:
Web Server
A server listens for incoming connections. For each new client, it creates a child process to handle that client while the parent keeps listening.
Shell (bash/sh)
When you type ls or grep, the shell creates a child process to run that command. The shell waits for the child to finish, then prints the prompt.
Parallel Processing
Split a big task (like processing 1000 files) into smaller chunks and assign each chunk to a separate child process. They all run at the same time.
Isolation / Safety
Run untrusted code in a child process. If it crashes or misbehaves, the parent is unaffected. This is used in browsers (each tab = separate process).
Every process in Linux (except init, PID 1) has a parent. When a process creates another, the creator is the parent and the new process is the child. This forms a tree structure called the process tree.
PID 300
PID 450
PID 512 (child of bash)
PID 513 (child of sshd)
You can see the process tree on your system with: pstree -p
Linux gives you four key system calls for managing process life cycles:
| System Call | Purpose | Phase |
|---|---|---|
fork() |
Create a new child process (copy of parent) | Birth |
execve() |
Replace process image with a new program | Transformation |
exit() |
Terminate a process, free all resources | Death |
wait() |
Parent waits for child; collects exit status | Cleanup |
Every process can find out who it is and who created it:
#include <stdio.h>
#include <unistd.h>
int main(void)
{
printf("My PID = %d\n", (int)getpid());
printf("My parent PID = %d\n", (int)getppid());
/* You can verify this with: ps -p <PID> -o pid,ppid,comm */
return 0;
}
ps -p <PID> -o pid,ppid,comm to confirm the values.This program forks a child and both print their PID/PPID. You can see the parent-child relationship clearly:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid;
printf("=== Before fork ===\n");
printf("Shell (grandparent) PID = %d\n", (int)getppid());
printf("This process PID = %d\n", (int)getpid());
pid = fork();
if (pid == -1) { perror("fork"); exit(1); }
if (pid == 0) {
/* Child */
printf("\n=== Child Process ===\n");
printf("Child PID = %d\n", (int)getpid());
printf("Child's parent PID= %d\n", (int)getppid());
exit(EXIT_SUCCESS);
} else {
/* Parent */
sleep(1); /* wait for child to print first */
printf("\n=== Parent Process ===\n");
printf("Parent PID = %d\n", (int)getpid());
printf("Child PID was = %d\n", (int)pid);
wait(NULL);
}
return 0;
}
This simulates how a web server creates a child for each “client” (we simulate 3 clients):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
/* Simulate handling a client request */
void handle_client(int client_id)
{
printf("[Worker PID=%d] Handling client #%d\n",
(int)getpid(), client_id);
sleep(2); /* simulate work */
printf("[Worker PID=%d] Done with client #%d\n",
(int)getpid(), client_id);
}
int main(void)
{
int num_clients = 3;
int i;
pid_t pid;
printf("[Server PID=%d] Starting...\n", (int)getpid());
for (i = 1; i <= num_clients; i++) {
pid = fork();
if (pid == -1) { perror("fork"); exit(1); }
if (pid == 0) {
/* Child handles this client */
handle_client(i);
exit(EXIT_SUCCESS);
}
/* Parent loops to accept next client */
printf("[Server] Spawned worker PID=%d for client #%d\n",
(int)pid, i);
}
/* Server waits for all workers */
for (i = 0; i < num_clients; i++)
wait(NULL);
printf("[Server] All clients handled. Shutting down.\n");
return 0;
}
A program is a static file on disk (e.g., /bin/ls). A process is a running instance of that program — it has memory, CPU state, open files, and a PID. Multiple processes can run the same program simultaneously.
PID 1 is the init process (or systemd on modern Linux). It is the first process started by the kernel and is the ancestor of all other processes. It is special because it has no parent and it adopts orphaned child processes.
Process-per-client provides isolation (a crash in one client handler doesn’t affect others), security (separate privilege levels are possible), and concurrency (multiple clients served at the same time).
pstree -p shows the full process tree with PIDs. ps auxf also shows parent-child relationships in a forest format. ps -o pid,ppid,comm shows PID, PPID, and command name.
When a parent exits before its child, the child becomes an orphan. The kernel automatically re-parents orphans to init (PID 1). Init then calls wait() on them when they exit, preventing zombies.
