Processes and how they are created
Every running program on Linux is a process with its own identity, memory, and resources. Processes are born by copying a parent and then becoming something new.
What a process is
A process is a running instance of a program, with its own virtual address space, open files, environment, credentials, and one or more threads. The kernel identifies each process by a process ID (PID) and records its parent's PID (PPID), so processes form a tree rooted at PID 1. Many processes can run the same program at once.
fork and exec
Linux creates processes in two steps. fork() makes a near-identical copy of the calling process; the child gets a new PID, and fork returns 0 in the child and the child's PID in the parent. The child usually then calls an exec function, such as execve(), which replaces its program with a new one while keeping the PID and open files. A shell running ls forks itself, and the child execs /usr/bin/ls.
Copy-on-write
Copying a large process's memory on every fork would be slow. Linux uses copy-on-write: parent and child initially share the same physical memory pages, marked read-only, and a page is copied only when one of them writes to it. Since a forked child usually calls exec immediately, most pages are never copied, making fork cheap.
Exit and wait
A process ends by calling exit() with a status code, or by being killed by a signal. Its parent collects the status with wait() or waitpid(). Until then, the dead process remains as a zombie, a process-table entry holding only its exit status. If a parent dies first, its children are adopted by PID 1 (or a designated subreaper), which reaps them.
Process states
A process is running or runnable (R), sleeping interruptibly while waiting for an event such as input (S), in uninterruptible sleep, usually waiting for disk or network storage I/O (D), stopped by a signal or debugger (T), or a zombie (Z). Many processes in state D can indicate storage problems, since they cannot be killed until the I/O completes.
Threads
Threads are multiple flows of execution within one process, sharing its memory and files but with separate stacks and registers. Linux implements threads as tasks created with clone() that share resources; each has its own thread ID, while the process ID is shared by the group. Multithreaded programs use cores in parallel but need synchronisation such as mutexes.
Foreground and background jobs
In an interactive shell, a command normally runs in the foreground. Adding & runs it in the background; jobs lists jobs; Ctrl+Z stops the foreground job; bg resumes it in the background; fg brings a job to the foreground. nohup or disown keeps a job running after you log out, and terminal multiplexers such as tmux keep whole sessions alive.
Worked example
Typing sleep 100 & in Bash prints a job number and PID, such as [1] 4321. The shell forked a child, which exec'd /usr/bin/sleep. ps -o pid,ppid,stat,cmd -p 4321 shows PPID equal to the shell's PID and state S, sleeping. If the shell exits without waiting and without nohup, the job usually receives a hangup signal; if it survives, it is reparented to PID 1 or a subreaper.
Key takeaways
A process is a running program with a PID, a parent (PPID), memory, files, and threads, forming a tree under PID 1. fork() copies a process and exec() replaces its program; shells fork and exec to run commands. Copy-on-write makes fork cheap. Processes exit with a status that parents collect with wait(); uncollected ones are zombies, and orphans are adopted by PID 1. States include R, S, D, T, and Z. Threads share a process's memory and are created with clone(). Shells manage foreground and background jobs with &, Ctrl+Z, bg, fg, and jobs; nohup, disown, and tmux keep work running after logout.
Flashcard
Running instance of a program
Check your understanding
When a shell runs ls, which sequence of system calls is used?
