Beginners Guide to Managing Processes Running on a Linux System

Definition of a Process

A process is a running instance of a launched, executable program. A process consists of:

  • An address space of allocated memory
  • Security properties including ownership credentials and privileges
  • One or more execution threads of program code
  • Process state

The environment of a process includes:

  • Local and global variables
  • A current scheduling context
  • Allocated system resources, such as file descriptors and network ports

An existing (parent) process duplicates its own address space (fork) to create a new (child) process structure. Every new process is assigned a unique process ID (PID) for tracking and security. The PID and the parent’s process ID (PPID) are elements of the new process environment. Any process may create a child process. All processes are descendants of the first system process, systemd for all the newer versions of Linux (e.g. CentOS/RHEL ).

process cycle in Linux - process states

Through the fork routine, a child process inherits security identities, previous and current file descriptors, port and resource privileges, environment variables, and program code. A child process may then exec its own program code. Normally, a parent process sleeps while the child process runs, setting a request (wait) to be signaled when the child completes. Upon exit, the child process has already closed or discarded its resources and environment. The only remaining resource, called a zombie, is an entry in the process table. The parent, signaled awake when the child exited, cleans the process table of the child’s entry, thus freeing the last resource of the child process. The parent process then continues with its own program code execution.

Describing Process States

In a multitasking operating system, each CPU (or CPU core) can be working on one process at a single point in time. As a process runs, its immediate requirements for CPU time and resource allocation change. Processes are assigned a state, which changes as circumstances dictate.

linux process states

Linux process states are illustrated in the previous diagram and described in the following table:

Running R TASK_RUNNING: The process is either executing on a CPU or waiting to run. Process can be executing user routines or kernel routines (system calls), or be queued and ready when in the Running (or Runnable) state.
Sleeping S TASK_INTERRUPTIBLE: The process is waiting for some condition: a hardware request, system resource access, or signal. When an event or signal satisfies the condition, the process returns to Running.
Sleeping D TASK_UNINTERRUPTIBLE: This process is also Sleeping, but unlike S state, does not respond to signals. Used only when process interruption may cause an unpredictable device state.
Sleeping K TASK_KILLABLE: Identical to the uninterruptible D state, but modified to allow a waiting task to respond to the signal that it should be killed (exit completely). Utilities frequently display Killable processes as D state.
Sleeping I TASK_REPORT_IDLE: A subset of state D. The kernel does not count these processes when calculating load average. Used for kernel threads. Flags TASK_UNINTERRUPTABLE and TASK_NOLOAD are set. Similar to TASK_KILLABLE, also a subset of state D. It accepts fatal signals.
Stopped T TASK_STOPPED: The process has been Stopped (suspended), usually by being signaled by a user or another process. The process can be continued (resumed) by another signal to return to Running.
Stopped T TASK_TRACED: A process that is being debugged is also temporarily Stopped and shares the same T state flag.
Zombie Z EXIT_ZOMBIE: A child process signals its parent as it exits. All resources except for the process identity (PID) are released.
Zombie X EXIT_DEAD: When the parent cleans up (reaps) the remaining child process structure, the process is now released completely. This state will never be observed in process-listing utilities.

Why Process States are Important

When troubleshooting a system, it is important to understand how the kernel communicates with processes and how processes communicate with each other. At process creation, the system assigns the process a state. The S column of the top command or the STAT column of the ps shows the state of each process. On a single CPU system, only one process can run at a time. It is possible to see several processes with a state of R. However, not all of them will be running consecutively, some of them will be in status waiting.

[[email protected] ~]$ top
1 root  20   0  244344  13684   9024 S   0.0   0.7   0:02.46 systemd
2 root  20   0       0      0      0 S   0.0   0.0   0:00.00 kthreadd
...output omitted...
[[email protected] ~]$ ps aux
root         2  0.0  0.0      0     0 ?        S    11:57   0:00 [kthreadd]
geek.     3448  0.0  0.2 266904  3836 pts/0    R+   18:07   0:00 ps aux
...output omitted..

A process can be suspended, stopped, resumed, terminated, and interrupted using signals. Signals are discussed in more detail later in this chapter. Signals can be used by other processes, by the kernel itself, or by users logged into the system.

Listing Processes

The ps command is used for listing current processes. It can provide detailed process information, including:

  • User identification (UID), which determines process privileges
  • Unique process identification (PID)
  • CPU and real time already expended
  • How much memory the process has allocated in various locations
  • The location of process stdout, known as the controlling terminal
  • The current process state
  • UNIX (POSIX) options, which may be grouped and must be preceded by a dash
  • BSD options, which may be grouped and must not be used with a dash
  • GNU long options, which are preceded by two dashes

For example, ps -aux is not the same as ps aux.

Perhaps the most common set of options, aux, displays all processes including processes without a controlling terminal. A long listing (options lax) provides more technical detail, but may display faster by avoiding user name lookups. The similar UNIX syntax uses the options -ef to display all processes.

[[email protected] ~]$ ps aux
root         1  0.1  0.1  51648  7504 ?        Ss   17:45   0:03 /usr/lib/systemd/syst
root         2  0.0  0.0      0     0 ?        S    17:45   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    17:45   0:00 [ksoftirqd/0]
root         5  0.0  0.0      0     0 ?        S<   17:45   0:00 [kworker/0:0H]
root         7  0.0  0.0      0     0 ?        S    17:45   0:00 [migration/0]
...output omitted...
[[email protected] ~]$ ps lax
4     0     1     0  20   0  51648  7504 ep_pol Ss   ?       0:03 /usr/lib/systemd/
1     0     2     0  20   0      0     0 kthrea S    ?       0:00 [kthreadd]
1     0     3     2  20   0      0     0 smpboo S    ?       0:00 [ksoftirqd/0]
1     0     5     2   0 -20      0     0 worker S<   ?       0:00 [kworker/0:0H]
1     0     7     2 -100  -      0     0 smpboo S    ?       0:00 [migration/0]
...output omitted...
[[email protected] ~]$ ps -ef
root         1     0  0 17:45 ?        00:00:03 /usr/lib/systemd/systemd -switched-ro
root         2     0  0 17:45 ?        00:00:00 [kthreadd]
root         3     2  0 17:45 ?        00:00:00 [ksoftirqd/0]
root         5     2  0 17:45 ?        00:00:00 [kworker/0:0H]
root         7     2  0 17:45 ?        00:00:00 [migration/0]
...output omitted...

By default, ps with no options selects all processes with the same effective user ID (EUID) as the current user, and which are associated with the same terminal where ps was invoked.

  • Processes in brackets (usually at the top of the list) are scheduled kernel threads.
  • Zombies are listed as exiting or defunct.
  • The output of ps displays once. Use top for a process display that dynamically updates.
  • ps can display in tree format so you can view relationships between parent and child processes.
  • The default output is sorted by process ID number. At first glance, this may appear to be chronological order. However, the kernel reuses process IDs, so the order is less structured than it appears. To sort, use the -O or –sort options. The display order matches that of the system process table, which reuses table rows as processes die and new ones are created. The output may appear chronological but is not guaranteed unless explicit -O or –sort options are used.