A single-threaded backend server does not execute continuously from startup to shutdown.
It runs while parsing a request, waits when no network data is available, becomes eligible to run when a packet arrives, runs again to build a response, and may wait once more while writing data.
The operating system needs a concise way to describe what can happen to the process next. That description is the process's state.
A process state tells the kernel whether a process is executing, able to execute, waiting for an event, deliberately stopped, or finished.
The state is part of the kernel's process bookkeeping. It changes many times during even a short program's lifetime.
Suppose a server calls a blocking operation to receive data, but no data has arrived.
The process cannot make progress. Letting it repeatedly check the socket would waste CPU time that another process could use. Instead, the kernel records that the process is waiting and allows other work to run.
When data arrives, the kernel changes the process's state so that it becomes eligible for CPU time again.
The state therefore answers a scheduling question:
Can this process make progress if the kernel gives it a CPU now?
If the answer is yes, the process is running or ready. If the answer is no because it needs an event, the process is waiting. If it has finished, it cannot execute again.
States and the associated wait bookkeeping let the kernel avoid two expensive mistakes:
The process's saved execution context preserves where it will continue. Its state records whether it is currently allowed and able to continue.
Operating-systems textbooks commonly describe a process using five states:
The important part is not memorizing five labels. It is understanding the events that move a process between them.
Only one transition leads into Running, and every process competing for the CPU has to pass through Ready to reach it.
This diagram is a model, not a literal list of every transition supported by every operating system. It captures the normal path through a process lifetime.
A process is new while the operating system is creating its execution environment.
The kernel may be assigning an identity, allocating process bookkeeping, preparing an address space, and creating the initial execution context. The process is not yet eligible to execute application instructions.
Once the required setup succeeds, the process moves to ready.
The new state is often too brief to observe with ordinary tools. Some operating systems do not expose it as a distinct user-visible state at all, even though process creation still requires a setup phase.
If creation fails, no usable process enters the ready population.
A ready process has everything it needs to execute except a CPU.
Its code and execution context are available. It is not waiting for data, a timer, or another event. The kernel can select it whenever an allowed CPU becomes available.
Ready processes are commonly organized in scheduler-managed structures called run queues. Being on a run queue does not mean the process is currently running. It means the process is a candidate to run.
On a single-core machine, several processes may be ready while only one is running.
The time a process spends ready but not executing contributes to scheduling delay. A system with many CPU-hungry ready processes can feel slow even when none of them is waiting for I/O.
A process is running when one of its threads is executing instructions on a CPU core.
At most one thread can execute on one logical CPU at an instant. A machine with eight logical CPUs can therefore run at most eight threads simultaneously, even if hundreds are ready.
While running, a process may:
Running does not mean the process is executing only application code. The same thread may cross into the kernel to request an operating-system service and still be the current running thread.
This distinction is important: process state and CPU privilege mode describe different things. Running versus waiting is a scheduling condition. User mode versus kernel mode is a protection level.
A process is waiting when it cannot make progress until some event occurs.
Common events include:
While genuinely blocked, the process does not need a CPU. Its execution context and resources still exist, but the scheduler does not treat it as ready.
This is an efficiency feature, not a failure.
When the event occurs, the process normally moves from waiting to ready, not directly to running. Becoming able to run does not guarantee immediate CPU access; other ready work may already be ahead of it.
The words waiting, blocked, and sleeping are often used for closely related ideas. Linux commonly reports these tasks as sleeping, while textbook state diagrams commonly label the state waiting or blocked.
A process becomes terminated when its execution has ended.
It may return normally from its entry function, request an exit, encounter a fatal error, or be terminated by the operating system. It will not execute more application instructions.
The kernel releases runtime resources such as its address space and open-resource references. It may retain a small completion record containing information such as the process ID and exit status until the process's parent collects that result.
The full process is no longer executing, but this temporary completion record explains the Linux zombie state discussed later in this chapter.
As with the new state, terminated can be a conceptual lifecycle state rather than a long-lived scheduler state. The process cannot return from terminated to ready.
State transitions occur because something changes in the process or the surrounding system.
The operating system has completed enough setup for the process to execute. It places the process among the runnable work.
The scheduler selects the process for a CPU. Its saved execution context becomes the CPU's active context.
The process is still able to execute, but the kernel lets other work use the CPU. This can happen when a time allocation ends, more urgent work becomes eligible, or the process voluntarily yields.
No external event is required before this process can run again. It remains ready.
The process requests an operation that cannot complete immediately. The kernel records what it is waiting for and removes it from the runnable population.
Only a running process can initiate a new wait, because code must execute to request the operation.
The awaited event occurs. The kernel marks the process runnable and places it in the appropriate scheduling structure.
A wakeup means “this process may run again.” It does not mean “this process runs immediately.”
The process finishes or is ended while the kernel is handling it. Its execution stops permanently and cleanup begins.
Real systems allow additional paths. For example, an external termination request can affect a process that was ready or waiting. The five-state diagram emphasizes the core lifecycle rather than every implementation-specific edge.
Waiting for an event does not always mean entering the waiting state.
Consider a program repeatedly checking a flag:
This is busy waiting. The process remains runnable and consumes CPU time while checking the same condition.
A blocking wait behaves differently:
If no data is available and the operation is configured to block, the kernel can put the caller to sleep. The task consumes no CPU while it waits and becomes runnable when data arrives.
| Property | Busy wait | Blocking wait |
|---|---|---|
| Process state | Ready or running | Waiting |
| How it learns of the change | Repeatedly checks the condition | The kernel records the awaited event |
| CPU cost | Consumes CPU time | Consumes no CPU while asleep |
Blocking is usually the efficient choice when the wait may be long. Busy waiting can still be useful for extremely short waits in carefully controlled low-level code, but it is costly when used for ordinary backend I/O.
Consider a single-threaded server that waits for a request, processes it, and sends a response.
Its state timeline may look like this:
The server may move between running, waiting, and ready thousands of times per second.
This is why a process's state is only a snapshot. By the time a monitoring command prints S or R, the process may already have transitioned again.
The five-state model separates ready from running and uses one general waiting state.
Linux uses a different internal model and exposes compact state codes through tools such as ps, top, and /proc/<PID>/status.
| Code | Meaning | Practical interpretation |
|---|---|---|
R | Running or runnable | Currently executing, or ready on a run queue |
S | Interruptible sleep | Waiting for an event; an applicable signal can interrupt the wait |
D | Uninterruptible sleep | Waiting in a kernel operation that ordinary signal handling does not interrupt |
T | Stopped | Suspended by a job-control or stop request |
t | Tracing stop | Stopped while controlled by a debugger or tracer |
Z | Zombie | Execution ended, but a minimal completion record remains |
X | Dead | Final internal state that should rarely be visible |
Some tools also show I for an idle kernel thread. Additional letters in the STAT column, such as l, s, +, <, or N, are modifiers rather than primary states.
The mapping to the textbook model is approximate:
R combines textbook ready and running.S and D are forms of textbook waiting.T and t represent deliberately stopped execution, which the five-state model does not show separately.Z and the rarely observed X belong to the termination part of the lifecycle.Understanding this mismatch prevents a common mistake: seeing R in ps does not prove that the task was on a CPU at the exact instant of observation. It may have been runnable and waiting its turn.
SS is Linux's common sleeping state.
A task in interruptible sleep is waiting for an event, such as data arriving, a timer expiring, or a child changing condition. The event can wake it. An applicable pending signal can also cause the wait to end early so the task can respond.
Despite the name, interruptible sleep does not mean the CPU is executing the process but can interrupt it. The process is not running. Interruptible describes which kinds of events may end the wait.
It is normal for a healthy, mostly idle backend service to spend much of its time in S. A server with nothing to process should sleep rather than consume a full CPU core.
DD means the task is waiting inside the kernel in an uninterruptible sleep.
This state is commonly associated with I/O, but it is not limited to physical disks. A task might be waiting on storage, a network filesystem, a device, a driver, or another kernel condition that requires the operation to reach a safe point before normal signal handling proceeds.
A brief appearance in D is not automatically a problem. A task can enter D, receive the required wakeup almost immediately, and continue.
A task that remains in D for a long time deserves investigation. It may indicate:
Sending SIGKILL does not necessarily make such a task disappear immediately. The signal can remain pending while the task stays in the uninterruptible wait. The task can act on termination only after the kernel wait reaches a point from which it can wake or return.
This behavior prevents the kernel from abandoning some low-level operations in an unsafe intermediate state. It also means that a persistent D state is often a symptom of a deeper I/O or kernel problem rather than an ordinary application shutdown issue.
T and tA stopped task is alive but deliberately prevented from executing.
Linux reports T when job control or an explicit stop request suspends the task. A shell uses this behavior when a foreground command is suspended.
The lowercase t indicates a tracing stop, commonly produced when a debugger pauses a process to inspect it.
Stopped differs from waiting:
Neither consumes CPU while stopped, but the reason and wakeup condition are different.
ZA zombie has finished executing. It cannot run, wait for I/O, or handle another request.
Most of its runtime resources have already been released. The kernel keeps only the small amount of information needed for its parent to learn how the process ended.
This makes Z fundamentally different from S or D. A sleeping process may continue after an event; a zombie's execution is over permanently.
A zombie consumes a process-table entry, not a CPU core. A persistent or growing zombie population indicates that parent processes are not collecting child completion information promptly.
Loading simulation...
Some state diagrams expand the five-state model with ready-suspended and blocked-suspended.
These states describe a process that is ready or waiting but has also been removed from main memory or explicitly suspended. The extra distinction was especially important in systems that swapped entire processes between memory and storage.
Modern systems often move individual memory pages rather than treating the whole process as swapped out. They also expose explicit stop, freeze, and tracing mechanisms that do not map exactly onto the classic suspended-state diagram.
The terminology therefore varies. When reading a state diagram, first ask what distinction its author is modeling:
Two diagrams can use different state counts while describing the same fundamental constraints.
For a single-threaded process, saying “the process is running” or “the process is sleeping” is usually clear enough.
A multithreaded process is more nuanced. One thread can execute while another waits for network data and a third is stopped in a debugger. Linux tracks scheduling state per task, which normally corresponds to a thread.
Within one process, thread 1 may be in state R while threads 2 and 3 are both in state S.
A tool that displays one row per process may summarize or show the state of the thread-group leader. To see individual Linux threads, use a thread-aware view:
This is why one state letter cannot always describe everything happening inside a multithreaded backend service.
You can create safe examples of running, sleeping, and stopped states from a shell.
Start a sleeping process:
Start a CPU-bound process:
Inspect both:
A typical sample looks like:
The exact values will vary. WCHAN identifies the kernel wait location when one is available. The sleep process is waiting for its timer and consumes essentially no CPU. The shell loop remains runnable and consumes a core.
Now stop the CPU-bound process:
Its primary state should appear as T.
Allow it to continue, then clean up both processes:
You can also read the state through /proc:
Because the shell must run to launch grep, the value is only a sample of the shell's state around the observation. Process states can change faster than a human-facing tool can display them.
A state code is a clue, not a diagnosis.
If many tasks remain R, the workload may be competing for CPU time. Compare the runnable population with the available CPU capacity and observe it across multiple samples.
If a service is mostly S while idle, that is usually healthy. If it is S while requests are stuck, determine what event or resource it is waiting for rather than assuming sleeping itself is the bug.
Persistent D tasks point attention toward I/O, filesystems, devices, or kernel waits. The WCHAN column, kernel logs, and I/O metrics can help narrow the cause.
A buildup of tasks in uninterruptible waits can also raise Linux load average while CPU utilization remains modest. Load average is not purely a measure of CPU usage.
T suggests an explicit stop or debugger. Z says execution has already ended and parent-side lifecycle handling needs attention.
Most importantly, state is instantaneous. A process that alternates rapidly between R and S may appear in either state depending on when it is sampled. Reliable diagnosis combines repeated state observations with CPU, I/O, latency, and application evidence.
The classic process lifecycle uses new, ready, running, waiting, and terminated states. Dispatch moves a ready process to running; preemption returns it to ready; a blocking operation moves it to waiting; and an event wakes it back to ready.
Linux exposes a different but related set of codes. R means running or runnable, S and D represent interruptible and uninterruptible waits, T and t represent stopped tasks, and Z represents an execution that has ended but still has a completion record.
The essential mental model is:
A process state tells whether an execution thread can make progress now and, if not, what condition prevents it.
5 quizzes