Program versus Process
A program is a passive file of instructions on disk; a process is one running instance of it with its own address space, state and PID — which is why one chrome binary can be twenty processes and why killing one leaves the file untouched.
The problem
/opt/google/chrome/chrome, and ps shows it running as PIDs 1201, 1229 and 1304, each using a different amount of memory, one of them at 90% CPU. If they are all "Chrome", what exactly is different between them, and what is shared?A file is not a running thing
A program is bytes on storage: machine code, constants, a table of what to load where, and the names of the libraries it needs. It has no memory, no CPU time, no open files, no PID. You can copy it, sha256sum it, and delete it while a process built from it keeps running (on Unix-style systems the mapped pages stay valid because the kernel holds a reference to the inode, not the name — see Inodes).
A process is what the kernel creates when it runs a program: a private virtual address space, a set of registers (saved when it is not on a CPU), a scheduling state, an identity (PID, owner, parent), and a table of resources it holds — open files, sockets, locks, timers. The program is the recipe; the process is the meal. The recipe does not change when the meal burns.
The distinction sounds trivial until you debug. "The program uses too much memory" is meaningless; a specific process at a specific moment uses memory. "Restart the program" means create a new process from the same file, with fresh state and a new PID. "Update the binary" changes the file but not the processes already built from the old bytes — every process started before the deploy keeps running the old code until it exits.
One executable, three processes
Running the same executable three times produces three processes that share almost nothing they can observe. Each has its own address space: the global variable counter at virtual address 0x4c2010 in PID 1201 is a different physical byte from counter at the same virtual address in PID 1229. Each has its own descriptor table, so descriptor 5 is a different socket in each. Each has its own exit status, its own scheduling history, and can be killed independently.
What they do share is invisible to them: the kernel maps the same physical pages of machine code into all three, because code is read-only and identical. Twenty Chrome processes cost one copy of Chrome’s text in RAM, not twenty. The RSS column in ps counts those shared pages in every process, which is why summing RSS across processes over-estimates total memory use; PSS in /proc/<pid>/smaps divides shared pages by the number of sharers.
$ ps -o pid,ppid,stat,rss,pcpu,comm -C chrome PID PPID STAT RSS %CPU COMMAND 1201 1180 Sl 312840 2.1 chrome ← browser process 1229 1201 Sl 189332 0.3 chrome ← GPU process 1304 1201 Rl 524116 89.7 chrome ← a renderer, busy 1305 1201 Sl 98120 0.0 chrome ← another renderer, idle
What a process owns
The kernel keeps one record per process — traditionally called the process control block, task_struct in Linux — and everything the process "has" is reachable from it. The Anatomy of a Process walks the fields. For now, the shape is: identity (PID, parent PID, uid/gid), a pointer to the address space, saved CPU registers, scheduling state and priority, the descriptor table, pending signals, resource limits, and accounting (CPU time consumed, page faults taken).
Because the record is the process, "a process exists" means exactly "the kernel has such a record". The moment the record is freed the PID may be reused — which is why holding a PID across time and assuming it still names the same process is a classic bug (kill by stale PID hitting an unrelated process).
- Address space: private virtual memory, code pages typically shared with other instances of the same program — The Virtual Address Space.
- Descriptor table: per-process; descriptors are inherited across
fork, not shared across unrelated processes — File Descriptors. - Identity and credentials: PID, PPID, uid/gid, on Linux capabilities and namespaces — Process Isolation: One Kernel, Many PID 1s.
State, briefly
At any instant a process is doing one of a handful of things: it is on a CPU (running), it could be on a CPU but none is free (ready/runnable), it is waiting for something that has not happened yet (blocked: a disk read, a packet, a lock, a timer), or it has exited and is waiting for its parent to collect the exit status. The busy renderer above is R; the idle ones are S, sleeping in a poll() on their IPC pipe.
That state is what the scheduler reads, and it is what you read in top when something is wrong. Process States gives the full machine, including the Unix-specific zombie and stopped states and why "blocked" is where most processes spend most of their lives.
Key points
- Program = passive bytes on disk. Process = a kernel record plus an address space, registers, state and resources built from those bytes.
- Running the same program N times gives N processes with private data, private descriptors and private PIDs; only read-only code pages are physically shared.
- Updating the binary does not change running processes; restarting means a new process with fresh state.
- A process exists exactly as long as its kernel record; PIDs are reused after that.
- Each process is always in one scheduling state — running, ready, blocked or exited.
Why does this exist?
Mechanisms are answers to constraints. Open each question before reading the answer.
▸Why separate the program from the process at all?
So that one file can be run many times concurrently, each run isolated from the others, and so that the file can be replaced while old instances finish.
▸Why share code pages between instances but not data pages?
Code is read-only and identical, so sharing is free and safe; data diverges immediately, so each process needs its own copy (created lazily via copy-on-write after fork).
One program, many processes
How it fails
What the failure looks like from inside real software.
- A deploy replaces the binary, but the old process keeps running old code for hours; the fix "is not live" until a restart.
- Summing RSS across a fleet of worker processes reports more memory than the machine has, because shared code pages are counted once per process.
- A supervisor stores a PID, the process dies, the PID is reused by something unrelated, and the supervisor later
kills the wrong process. - Two instances of the same program both write to the same log file with their own buffered offsets and interleave garbage, because the file is shared but the buffers are per-process.