Yes, we're now running our Black Friday Sale. All Access and Pro are 33% off until 2nd December, 2025:
Linux Processes
Last updated: April 30, 2025
1. Overview
Understanding processes is crucial for system administrators aiming to streamline their workflow and boost productivity. In Linux, a process is created whenever a program or command is executed. Additionally, applications can initiate multiple processes to perform various tasks. As a result, processes enable multitasking within the system.
In this tutorial, we’ll explore the concept of Linux processes, their various states and types, and the essential commands for monitoring and managing them.
2. Basics of Linux Processes
In Linux, a process is an instance of a running command, program, or application.
2.1. Metadata
Each process is linked with metadata:
- unique Process ID (PID)
- command used to initiate the process
- current process state
- resource usage details
This information includes both mutable and immutable data.
2.2. Initiation and Management
The Linux kernel manages processes and schedules their execution based on priority and system resource availability. The very first process started by the kernel during boot is historically called init (now often systemd), which initializes the system and launches other processes.
Every process goes through a complete lifecycle, from creation to termination. During its lifetime, it carries out its intended task and can create new processes using a mechanism called forking. This enables multiple processes to run concurrently.
2.3. Run Context
By default, processes are initiated in the foreground, meaning they interact directly with the terminal and occupy it until completion. These foreground processes are useful for tasks that require continuous interaction with the user. However, we can send processes to the background, so they can run without occupying the terminal.
Understanding the difference between foreground and background processes is crucial in interactive shell environments. Overall, foreground processes take over the terminal, while background processes run independently, freeing it up.
3. Types of Processes
There are several types of processes in Linux, categorized based on their relationship with other processes and their execution environment:
- Parent Process: original process that spawns one or more child processes
- Child Process: processes created by a parent process using the fork() system call
- Orphan Process: child process whose parent has terminated and is now adopted by init
- Zombie Process: process that has completed execution but still has an entry in the process table
- Daemon Process: background processes that run without user interaction, typically system or service-related process
Of course, each process type plays a distinct role in how the system operates and responds to tasks.
4. Process States
As mentioned earlier, processes in Linux go through different states during their lifecycle:
- Running (R): actively executing instructions on the CPU
- Sleeping (S/D): waiting for an event or resource, such as disk I/O (S indicates an interruptible sleep, while D indicates an uninterruptible sleep)
- Stopped (T): execution paused, typically by a signal or through job control commands
- Zombie (Z): execution completed, but it remains in the process table because its parent hasn’t yet read its exit status
- Waiting (W): ready to run, but waiting for a condition to become true or for resources
Notably, waiting is a rare process state that’s either represented differently or merged with other sleep states in modern systems.
5. Monitoring and Viewing Processes
Now, let’s explore some Linux commands commonly used to view, monitor, and find system processes.
5.1. Using the ps Command
The ps (process status) command is a common Linux tool that displays information about current processes.
We can run the ps command to list active processes in the current terminal:
$ ps
PID TTY TIME CMD
7520 pts/0 00:00:00 bash
7735 pts/0 00:00:15 firefox
7881 pts/0 00:00:00 Socket Process
7910 pts/0 00:00:00 Privileged Cont
…
8167 pts/0 00:00:00 Utility Process
8280 pts/0 00:00:00 ps
The output shows the Process ID (PID), Terminal Type (TTY), CPU Time, and the command that initiated the process.
Moreover, we can use various flags with the ps command to obtain more detailed output. For instance, we can run the ps command with the -a flag to display processes from all users and the -u flag to show detailed user-oriented output, including the users who own the processes and additional resource usage information:
$ ps -au
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
linuxfe+ 1547 0.0 0.0 171048 6016 tty2 Ssl+ 03:41 0:00 /usr/libexec/
linuxfe+ 1551 0.0 0.2 231700 15872 tty2 Sl+ 03:41 0:00 /usr/libexec/
linuxfe+ 7520 0.0 0.0 19924 5376 pts/0 Ss 05:32 0:00 bash
linuxfe+ 7735 47.6 2.3 2563560 139448 pts/0 Rl 06:03 0:02 /snap/firefox
linuxfe+ 7881 10.5 0.7 208112 46464 pts/0 Sl 06:03 0:00 /snap/firefox
linuxfe+ 7882 0.0 0.6 2555348 41220 pts/0 S 06:03 0:00 /snap/firefox
linuxfe+ 7900 1.0 0.0 21328 3328 pts/0 R+ 06:03 0:00 ps -au
This is a common way to quickly check processes that exist on the system.
5.2. Using the top Command
top (table of processes) is the default system monitor command in most Linux distributions, providing a real-time view of running processes and system usage. It shows output in order of decreasing CPU usage, with the most resource-heavy processes at the top.
For demonstration, let’s run the top command to get a dynamic view of all running processes in Linux:
$ top
top - 06:12:20 up 2:32, 1 user, load average: 0.60, 0.46, 0.27
Tasks: 199 total, 2 running, 196 sleeping, 1 stopped, 0 zombie
%Cpu(s): 4.2 us, 10.5 sy, 0.0 ni, 76.8 id, 0.0 wa, 0.0 hi, 8.4 si, 0.0 st
MiB Mem : 5894.9 total, 695.5 free, 1433.9 used, 3765.5 buff/cache
MiB Swap: 2048.0 total, 2048.0 free, 0.0 used. 4128.1 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1688 linuxfe+ 20 0 3847172 415908 152908 R 29.4 6.9 3:15.48 gnome-s+
…
Furthermore, we can view dynamic system performance, including CPU and memory usage, and details of running processes like PID, user, and resource consumption in the output of the top command. We can exit this view by pressing the q key.
5.3. Using the htop Command
htop is a more user-friendly, colorful, and interactive alternative to the top command in Linux. It displays real-time information about Linux processes and offers easier mouse and scroll navigation.
Firstly, we install the htop command in Linux using the native package manager, depending on the distribution:
$ sudo apt install htop
Then, we can run the htop command to view Linux process information:
$ htop
Moreover, the -u flag displays processes running under the specific user:
$ htop -u root
For instance, the output below displays the processes running under the root user:
Here, we can press the F10 key to quit.
5.4. Using the atop Command
atop is a newer and more detailed monitoring tool than top and htop. It offers comprehensive insights into system and process-level resource usage, including CPU, memory, secondary storage I/O, and network statistics.
First, we install atop on Linux:
$ sudo apt install atop
Afterward, we can run the atop command:
$ atop
The output displays real-time process details such as PID, user, CPU and memory usage, I/O, process state, and the related command:
Now that we’ve covered a few popular Linux commands to monitor processes, let’s explore the pgrep command, which is used to find the process ID of a specific process.
5.5. Using the pgrep Command
The pgrep command in Linux is used to search for the process IDs (PIDs) of processes based on their name or other attributes.
For example, we can find the PID of a Firefox process running in the foreground:
$ pgrep firefox
8788
Additionally, we can use the -u flag to specify a user and list the PIDs of all processes running under that user:
$ pgrep -u root
1
2
3
…
10592
10595
Furthermore, we use the -n flag with the -u flag to find the newest (most recently started) process owned by a specific user and return its PID:
$ pgrep -nu root
10627
Now, we can monitor and find Linux processes easily in a way that also enables easier parsing and automation.
6. Managing Linux Processes
Next, let’s discuss how we can start, stop, kill, or change the priority of processes in Linux.
6.1. Initializing a Process
As mentioned earlier, a process begins when a command is executed. It can run in the foreground or be placed in the background by appending an ampersand (&).
So, we can start a process by running a command, program, or script. For instance, we can run Codelite to start its process:
$ codelite
Similar to a foreground process, we can start a process in the background by appending an ampersand (&) to the command in the shell:
$ codelite &
After this, let’s use the ps command to verify whether the process has been initiated:
$ ps
PID TTY TIME CMD
11034 pts/1 00:00:00 bash
11153 pts/1 00:00:04 codelite
11230 pts/1 00:00:00 ps
Notably, we can observe that the Codelite process is running in Linux.
6.2. Stopping a Process
In most cases, we stop a process running in the foreground by simply pressing CTRL + C.
However, we can also use the kill command with the -STOP flag to stop a background process gracefully:
$ kill -STOP 11153
In the above command, 11153 is the PID of the process we want stopped. This way, we place the process in a paused state, making it eligible for resumption later.
6.3. Killing a Process
We can terminate a process by using the kill command with its PID:
$ kill 11153
However, if the process doesn’t terminate, we can use the -9 flag to send a stronger kill signal:
$ kill -9 11153
Alternatively, the pkill or killall commands terminate a process by its name instead of its PID:
$ pkill codelite
$ killall codelite
Thus, we should have successfully terminated the CodeLite process.
6.4. Changing Process Priority
Processes are assigned priority values (known as nice values) that affect CPU scheduling. The range spans from -20 (highest priority) to 19 (lowest). By default, a process runs with a nice value of 0. Interestingly, only the root user can assign negative nice values.
We use the nice command to start a process with a specific priority. On the contrary, we use the renice command to change the priority of an existing process.
For demonstration, let’s start the Firefox process in the background with a priority of 10:
$ nice -n 10 firefox &
At this point, we can change the priority of the above process by using the renice command with its PID and the new priority value:
$ sudo renice -n 5 -p 11418
11418 (process ID) old priority 10, new priority 5
Thus, we’ve successfully changed the priority of the Firefox process from 10 to 5.
7. Conclusion
In this article, we discussed how Linux processes are initiated whenever a program, command, or application is executed. They’re the core reason for user-level multitasking in Linux. Moreover, we explored different types and states of processes. Additionally, we covered commands like ps, pgrep, htop, top, and atop for monitoring processes. Lastly, we discussed the kill, nice, and renice commands for managing processes.