Course outline · 0% complete

0/28 lessons0%

Course overview →

PIDs: how the OS names processes

lesson 3-2 · ~9 min · 8/28

Every process gets a number

The OS gives each process a PID, a process ID, which is a unique positive number assigned when it starts. PIDs are how you refer to a process when talking to the OS: pause 4021, report how much memory 4021 is using, kill 4021.

Processes also form a family tree, and whatever starts a process becomes its parent. Your terminal, itself a shell process, is the parent of the python3 process it launches.

CallReturns
os.getpid()my own PID
os.getppid()my parent's PID

The tree has a root. Every process traces back through its parents to the first process the kernel starts at boot, which is PID 1, and that fact is what makes the whole table a single connected structure rather than a flat list.

terminal, pid 812web server, pid 903python3, pid 5001python3, pid 5002two processes of one program, each with its own private memorypid 1, started at boot
Every process has a parent, and the chain runs back to PID 1 at boot.

Facts about a PID that are always true

The actual number changes every run, since the OS hands out fresh ones, so the code prints properties instead of values.

import os

pid = os.getpid()
parent = os.getppid()
print("my pid is a positive number:", pid > 0)
print("my parent has a different pid:", parent != pid)

Output

my pid is a positive number: True
my parent has a different pid: True

Both statements hold on every machine and every run. PIDs are always positive, and a process can never be its own parent.

Adding a temporary print(pid) makes the point vivid, because the number differs on each run. That is direct proof that each run is a brand new process rather than a resumption of the last one.

The raw numbers, which differ every time

There is no fixed expected output here, because the values change on every run and every machine.

import os

print("pid:", os.getpid())
print("parent pid:", os.getppid())

A new process per run means a new PID per run, and the parent is whatever launched the code, usually a shell or an editor.

PIDs are recycled rather than infinite. The OS counts up to a system maximum and then wraps around to reuse numbers belonging to processes that have since exited, which is why a PID identifies a process only for as long as that process is alive.

Seeing processes from your own terminal

On macOS or Linux, these commands read the real process table:

ps aux        # snapshot of every process: PID, owner, CPU%, memory
top           # live, updating view (press q to quit)
ps aux | grep python   # only rows mentioning python
kill 4021     # politely ask process 4021 to quit
kill -9 4021  # force it (the OS just erases it, no cleanup)

The PID column is the same number os.getpid() reports from inside the process. On Windows, Task Manager shows the same table behind a graphical interface.

CommandAsks the OS for
ps auxone snapshot of the table
topthe same table, refreshed continuously
killdelivery of a signal to one PID

The difference between kill and kill -9 is worth remembering. The first asks the process to shut down and lets it save work and close files, while the second tells the kernel to remove it immediately with no chance to clean up.

Reading two python3 rows in ps output

Two rows for python3 with PIDs 5001 and 5002 mean two separate python3 processes, each with its own private memory.

Each row of the process table is one process, so two rows are two independent running instances of the same program, exactly like the two-terminal example in lesson 3-1.

Killing 5001 leaves 5002 untouched, since they share no memory and neither is the other's parent.

ObservationConclusion
same name, two PIDsone program, two processes
different memory columnsseparate private memory
kill onethe other keeps running

This is also the normal way production servers run. Four worker processes of the same program is four rows in ps, and losing one costs a quarter of the capacity rather than the whole service.

The name for the process that started another

In the process family tree, the process that started another one is its parent.

Every process is started by another process, and getppid literally means get parent process ID. The chain runs all the way up to the very first process the kernel starts at boot.

RelationshipTerm
the process that launched meparent
a process I launchedchild
the first process at bootPID 1, the root of the tree

The relationship is not just naming. A parent can wait for its child, read the child's exit code, and is notified when the child dies, which is exactly the mechanism the next lesson uses.