Page Body

Viewing Process Information With the ps Command

A process is an instance of one or more related tasks executing on a GNU/Linux system. It is distinct from a program or a command. A single program may simultaneously start several processes.

Note: If you are not familiar with the GNU/Linux command line interface, review the Conventions page before proceeding.

Process Identification (PID, PPID)

Some processes are independent of one another, while others are related (e.g., a parent process and its child processes). Each process is associated with a unique process ID, or PID, which serves to identify the process.

All processes know their parent process identity (PPID) and every process can spawn their own processes, i.e., their child processes. The only process that does not have a parent process is the pseudo process, which has a PID of 0. It is generated during system startup and creates the init process, which has a PID of 1. The init process becomes the ancestor of all other processes on the system.

Process Environment

Every process has an environment, which includes its user and group assignments and its current directory. This environment is inherited by the process's child processes. Changes to this environment by the child processes are not seen by and do not affect the parent process (i.e., the process environment is inherited, not shared).

The kernel and operating system allocate resources for processes. Processes are isolated from one another, so one process cannot normally access the resources of another process. A critical kernel function called the scheduler constantly shifts processes on and off of the Central Processing Unit (CPU), sharing time according to relative priority. This process is referred to as pre-emptive multitasking.

Process Priority

Processes have nice values, which range from -20 (least nice) to 19 (most nice). There is an inverse relation between how nice a process is and its priority. The higher the value, the nicer you are being towards your system's other users, by giving your own process a lower priority. A process's priority dynamically changes, based on its prior behavior. Interactive processes (i.e., those that often do input and output) are favored over those that just consume CPU time.

At any given moment in the kernel, processes also have a separate priority value that is distinct from a process's nice value. This priority value is the real priority for a process at the moment inside of the kernel, while the nice value is a suggestion for the kernel about the priority that the process should have.

Process Types

There are system processes and user processes. A system process is created when the init process loads a daemon. A user process is created when a user enters a command at the command line interface (CLI). User processes are associated with a shell session, while system processes are not.

Processes can be further divided into five different types:

  1. Interactive Processes Processes that need to be started by the user and are associated with a terminal.
  2. Batch Processes Automatic processes that are scheduled from and then disconnected from the terminal.
  3. Daemons Server processes that continuously run in the background, which are often started by init during system startup.
  4. Threads Lightweight processes. These processes are tasks that run under the umbrella of a main process, and they do share memory and other resources. However, they are scheduled and run by the system on an individual basis.
  5. Kernel Threads Kernel tasks that users neither start nor terminate, and have little control over.

Process States

When a process is executing on a CPU, it is an an operating state.

When a process is waiting to be granted a share of CPU time (i.e., a time slice), it is in a running state. These processes reside on a run queue. On a system with multiple CPUs (or cores), each CPU/core has its own run queue.

When a process is generally waiting for an event to occur before it can resume, it is in a sleep state. At any given time, most processes are in the sleep state. These processes reside on a wait queue.

Processes that have been stopped by job control are in a stopped state.

Sometimes, a child process completes, but its parent process has not inquired about its state (i.e., the parent process has not successfully picked up the child process's exit status). This kind of process is in a zombie state. It is not really alive, but still shows up in a system's list of processes. These kinds of processes are harmless and are expunged once their parent process terminates.

More specifically, a process on a GNU/Linux system is always in one of nine states:

  1. Deep Uninterruptible Sleep (D) The process is waiting for an event and cannot be disturbed. These processes can only be removed by rebooting the system.
  2. Idle (I) An idle kernel thread.
  3. Runnable (R) A running or runnable process.
  4. Interruptible Sleep (S) The process is waiting for an event, typically input or output.
  5. Temporarily Stopped (T) The process was temporarily stopped by a job control signal (SIGTSTP).
  6. Tracing Stop (t) The process was stopped by the debugger during tracing.
  7. Paging (W) Process state not valid since the 2.6.xx kernel.
  8. Dead (X) A process state that should never be seen.
  9. Defunct Zombie (Z) A process that has been terminated, but not reaped by its parent.

Real and Effective Identification (RUID, EUID, RGID, EGID)

ID Definition
RUID The user that started the process
EUID The user that determines the access rights used by the process
RGID The group that started the process
EGID The group that determines the access rights used by the process

The RUID/EUID and RGID/EGID for processes are not necessarily the same.

Load Average and System Utilization

Each process in a runnable state on a GNU/Linux system has a load number of 1. The average of these numbers for a given period of time is referred to as a system's load average.

On a GNU/Linux system, the load average takes into account processes that:

  • are actively running on the CPU
  • are considered runnable, but are waiting for a CPU to become available
  • cannot be awakened easily and are in an uninterruptible sleep state

The load average can be viewed with the uptime, w, and top commands. The values are given for the last minute, last five minutes, and last fifteen minutes. High values for the last five and fifteen minutes may be a cause for concern.

How you interpret the load average values depends on the number of CPUs/cores your system has. For a multi-core system, use the number of cores to calculate the system utilization. You can determine the number of cores on your system with the nproc command.

System Percent Utilization = (Load Average Number / Number of System CPUs/Cores) * 100

The ps Command

The ps command displays all processes that are running under the current terminal.

$ ps
  PID TTY          TIME CMD
 7287 pts/0    00:00:00 bash
 7301 pts/0    00:00:00 ps

If you want to view a line for a specific process, you can provide its PID to ps as an argument.

$ ps 19
   19 ?        S      0:00 [kdevtmpfs]

The ps command has many options, but unlike most GNU/Linux commands, it has two different styles that you can employ (and which you can see previewed in the output of the commands above). The options for these styles accomplish mostly the same things, but they differ in how they are implemented.

The first ps style is the System V style, and these are some of its most useful options:

Display all processes associated with a terminal, except for those associated with session leaders (i.e., the parent shell of a terminal or window)
Display PIDs associated with the command name given as an argument to the option
Display every process on the system
Use a full-format listing
Display the process hierarchy
Use a long-format listing; like the -f option, but with more information
Show thread information with processes, where LWP is the thread ID, and NLWP is the number of threads
Show thread information after processes
Specify a user-defined format; this option can be provided a comma-separated list of attributes (e.g., stat, priority, pid, pcpu, and comm) as arguments; for example, to only view pid and stat information for processes running under the current terminal you could do ps -o pid,stat
Allows ps to accept a comma-separated list of PIDs as arguments
Displays process information for the current user; you can provide this option a username as an argument to only view processes for that user

The second ps style is the older BSD style. Some of its most helpful options are:

Display all processes associated with a terminal, or list all processes when used with the x option
Use a long-format listing; like u, but outputs extra information, e.g., process priority
Specify a user-defined format; this option can be provided a comma-separated list of attributes as arguments (e.g., stat, priority, pid, pcpu, and comm)
Allows ps to accept a comma-separated list of PIDs as arguments
Display only running processes
Display user-oriented format
Display processes owned by the username provided to the option as an argument; the username argument is required for this option
Display processes that are not associated with a terminal, or list all processes when used with the a option

An example can help demonstrate the differences between the two ps styles. The following command can be used to view all processes for all users. It uses a full-format listing and uses the System V style of ps (output is limited to the first 10 lines via the use of the head command):

$ ps -ef | head
root         1     0  1 22:16 ?        00:00:06 /sbin/init config nopersistence noprompt splash noautologin
root         2     0  0 22:16 ?        00:00:00 [kthreadd]
root         3     2  0 22:16 ?        00:00:00 [rcu_gp]
root         4     2  0 22:16 ?        00:00:00 [rcu_par_gp]
root         6     2  0 22:16 ?        00:00:00 [kworker/0:0H-kblockd]
root         9     2  0 22:16 ?        00:00:00 [mm_percpu_wq]
root        10     2  0 22:16 ?        00:00:00 [ksoftirqd/0]
root        11     2  0 22:16 ?        00:00:00 [rcu_sched]
root        12     2  0 22:16 ?        00:00:00 [migration/0]

The columnar information for each process is:

Process EUID
Process ID
Parent Process ID
Processor Utilization; the integer value of the percent usage over the lifetime of the process
Starting time or date of the process
Controlling Terminal
Cumulative CPU Time

Here is the comparable BSD style version of the command:

$ ps aux | head
root         1  1.4  0.2 171032 11024 ?        Ss   22:16   0:06 /sbin/init config nopersistence noprompt splash noautologin
root         2  0.0  0.0      0     0 ?        S    22:16   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        I<   22:16   0:00 [rcu_gp]
root         4  0.0  0.0      0     0 ?        I<   22:16   0:00 [rcu_par_gp]
root         6  0.0  0.0      0     0 ?        I<   22:16   0:00 [kworker/0:0H-kblockd]
root         9  0.0  0.0      0     0 ?        I<   22:16   0:00 [mm_percpu_wq]
root        10  0.0  0.0      0     0 ?        S    22:16   0:00 [ksoftirqd/0]
root        11  0.0  0.0      0     0 ?        I    22:16   0:00 [rcu_sched]
root        12  0.0  0.0      0     0 ?        S    22:16   0:00 [migration/0]

The columnar information displayed is similar to the System V style, but distinct:

Process EUSER
Process ID
CPU utilization of the process
Memory utilization of the process
Virtual memory size of the process in KiB (1024-byte units)
Process's resident set size, the non-swapped physical memory that a task has used in kiloBytes
Controlling Terminal
Multi-character process state
Starting time or date of the process
Cumulative CPU Time


ps has a comprehensive manual page that you can view with the ps man command, or online.


Enjoyed this post?

Subscribe to the feed for the latest updates.