Understanding and Managing Linux Processes

An introduction to processes management in Linux and Unix
August 13, 2024 by
Understanding and Managing Linux Processes
Hamed Mohammadi
| No comments yet

Linux and other modern operating systems excel at multitasking by rapidly switching between different running programs. This illusion of simultaneous activity is made possible through the use of processes. Essentially, processes are how the system organizes and manages these programs as they compete for the CPU's attention.

When your computer slows down or an application freezes, it often indicates an issue with a process. This post explores command-line tools that can help you diagnose and resolve such problems by providing insights into running programs and their behavior.


How a Process Works Under systemd

In modern Linux systems, the process hierarchy is orchestrated primarily by systemd. This system and service manager replaces the traditional init process, offering a more robust and efficient approach.

Upon system boot, the kernel initializes essential components as processes and hands over control to systemd. This process manager then oversees the startup of system services, defined and managed through unit files (typically found in /etc/systemd/system). These units can represent various system components, including services, mount points, network interfaces, and more.

Many system services operate as daemons, background processes that run continuously without direct user interaction. These daemons handle tasks like network management, file system checking, and printing.

Processes form a hierarchical structure, with a parent process creating child processes. The kernel tracks vital information about each process, including its unique Process ID (PID), memory allocation, and execution state. Additionally, processes inherit ownership and permissions from their parent, similar to file systems.


Viewing Processes

To get a snapshot of running processes on a Linux system, the ps command is a fundamental tool. While it offers many options, let's start with the basics. A simple ps command lists processes associated with the current terminal:

$ ps

This typically displays a brief overview, including the process ID (PID), terminal (TTY), and command name. To see a broader picture, use the x option:

$ ps x

This shows all processes owned by the current user, regardless of their terminal. For extensive output, consider piping the results to less:

$ ps x | less

Process States

  • R: Running. This means the process is running or ready to run.

  • S: Sleeping. The process is not running; rather, it is waiting for an event, such as a keystroke or network packet.

  • D: Uninterruptible sleep. The process is waiting for I/O such as a disk drive.

  • T: Stopped. The process has been instructed to stop. You’ll learn more about this later in the chapter.

  • Z: A defunct or “zombie” process. This is a child process that has terminated but has not been cleaned up by its parent.

  • <: A high-priority process. It’s possible to grant more importance to a process, giving it more time on the CPU. This property of a process is called niceness. A process with high priority is said to be less nice because it’s taking more of the CPU’s time, which leaves less for everybody else.

  • N: A low-priority process. A process with low priority (a nice process) will get processor time only after other processes with higher priority have been serviced.

The process state may be followed by other characters. These indicate various exotic process characteristics. See the ps man page for more details. Another popular set of options is aux (without a leading dash). This gives us even more information.

$ ps aux

This set of options displays the processes belonging to every user. Using the options without the leading dash invokes the command with “BSD-style” behavior. The Linux version of ps can emulate the behavior of the ps program found in several different Unix implementations. With these options, we get the additional columns.

BSD Style ps Column Headers

  • USER: User ID. This is the owner of the process.

  • %CPU: CPU usage in percent.

  • %MEM: Memory usage in percent.

  • VSZ: Virtual memory size.

  • RSS: Resident set size. This is the amount of physical memory (RAM) the process is using in kilobytes.

  • START: Time when the process started. For values over 24 hours, a date is used.


Viewing Processes Dynamically with top

While ps offers a static snapshot of system processes, top provides a dynamic, real-time view of system resource utilization.

Running top displays a continuously updated list of processes sorted by CPU usage, along with key system metrics.

Top Output Overview

The top display is divided into two main sections:

System Summary:

  • uptime: System uptime and number of users.

  • load average: System load over the past 1, 5, and 15 minutes.

  • tasks: Total number of processes, running, sleeping, stopped, and zombie processes.

  • CPU(s): CPU usage, broken down by user, system, idle, and other states.

  • KiB Mem: Physical memory usage, including total, used, free, shared, buffered, and cached.

  • KiB Swap: Swap memory usage (if enabled).

Process List:

  • PID: Process ID.

  • USER: Process owner.

  • PR: Process priority.

  • NI: Nice value (process priority adjustment).

  • VIRT: Virtual memory size.

  • RES: Resident memory size.

  • SHR: Shared memory size.

  • S: Process state (R: running, S: sleeping, D: uninterruptible sleep, T: stopped, Z: zombie, etc.).

  • %CPU: CPU usage percentage.

  • %MEM: Memory usage percentage.

  • **TIME+: Total CPU time used by the process.

  • COMMAND: Process command name.

Navigating top

To interact with top, use the following keys:

  • h: Display help information.

  • q: Quit top.

  • P: Sort processes by CPU usage.

  • M: Sort processes by memory usage.

  • k: Kill a process (use with caution).

While graphical system monitors offer a similar overview, top is often preferred for its speed, efficiency, and comprehensive information.


Controlling Processes

Let's take control. Now that we can observe system processes, it's time to interact with them. We'll use the simple xlogo program as a test subject. This program, part of the X Window System, displays a resizable window featuring the iconic X logo. Let's start by understanding xlogo's behavior.

$ xlogo

Once you execute the xlogo command, a small window displaying the X logo should appear on your screen. Ignore any potential warning messages. To confirm xlogo is running, try resizing its window. If the logo adapts to the new size, the program is active. Note that your shell prompt remains unavailable until you close the xlogo window, indicating the shell's wait for program completion.

Interrupting a Process

Let's see how to stop a running program. Start xlogo again and verify it's running. Then, in your terminal, press Ctrl+C.

$ xlogo # Start xlogo and the press CNTR+C
$

Pressing Ctrl+C sends an interrupt signal to the program, typically causing it to terminate. You'll notice the xlogo window closes, and the shell prompt returns. While this method works for many programs, it's essential to remember that not all applications respond to this signal.


Putting a Process in the Background

Suppose we want to run xlogo without preventing us from using the terminal. We can achieve this by placing xlogo in the background. Imagine the terminal as having a foreground (where commands and their output are displayed) and a background (where processes run without occupying the foreground). To start a program in the background, simply append an ampersand (&) to the command.

$ xlogo &
[1] 7678

After running xlogo in the background with the ampersand (&), you'll notice the xlogo window appears, and the shell prompt returns immediately. However, you'll also see a message indicating a new job has been started. This is part of the shell's job control feature, which allows you to manage background processes.

The message provides a job number (e.g., [1]) and the process ID (PID) of the background process. You can verify its existence using the ps command.

To list all jobs running in the background, use the jobs command. This will display a list of active jobs, including their job numbers and status.

$ jobs
[1]+  Running  xlogo &

The results show that we have one job, numbered 1; that it is running; and that the command was xlogo &.


Returning a Process to the Foreground

A process running in the background is unaffected by keyboard input, including the Ctrl+C interrupt. To bring a background process back into the foreground, use the fg command.

$ jobs
[1]+  Running       
         xlogo &
$ fg %1
xlogo

To bring a background job to the foreground, use the fg command followed by the job number (preceded by a percent sign). If only one background job exists, the job number is optional. For instance, fg %1 brings job 1 to the foreground. To terminate the foreground process once it's resumed, press Ctrl+C as usual.

Sometimes, you might want to temporarily suspend a foreground process without terminating it. This is useful when you need to run another command and later return to the suspended process. To suspend a process, press Ctrl+Z. Let's try this: start xlogo, and then press Ctrl+Z.

$ xlogo
[1]+ Stopped xlogo
$

Once you've suspended xlogo with Ctrl+Z, the program becomes unresponsive. You can verify this by trying to resize the window. To continue the program, you have two options:

  1. Foreground: Use the fg command to bring the process back into the foreground.

  2. Background: Use the bg command to resume the process in the background.


$ bg %1
[1]+ xlogo &
$


Similar to fg, the bg command can be used without a job number if there's only one background job. Moving a process from foreground to background is particularly useful when you accidentally launch a graphical application without the ampersand (&).

Why run graphical programs from the command line?

  • Accessibility: Programs might not have a menu entry in your window manager.

  • Troubleshooting: Command-line launches can reveal error messages hidden in graphical interfaces. Sometimes, programs that fail to start graphically can be successfully launched and diagnosed from the command line.

  • Additional options: Many graphical applications offer command-line options for specific behavior.


Signals

The kill command is often used to terminate processes, but it's more accurately described as a signal sender. Signals are a fundamental mechanism for the operating system to communicate with processes.

To illustrate, let's run xlogo in the background and then terminate it using kill:

$ xlogo &
[1] 8154
$ kill 8154
[1]+  Terminated    xlogo

We first launch xlogo in the background. The shell prints the jobspec and the PID of the background process. Next, we use the kill command and specify the PID of the process we want to terminate. We could have also specified the process using a jobspec (for example, %1) instead of a PID.

While this is all very straightforward, there is more to it than that. The kill command doesn’t exactly “kill” processes; rather, it sends them signals. Signals are one of several ways that the operating system communicates with programs. We have already seen signals in action with the use of ctrl-C and ctrl-Z. When the terminal receives one of these keystrokes, it sends a signal to the program in the foreground. In the case of ctrl-C, a signal called INT (interrupt) is sent; with ctrl-Z, a signal called TSTP (terminal stop) is sent. Programs, in turn, “listen” for signals and may act upon them as they are received. The fact that a program can listen and act upon signals allows a program to do things such as save work in progress when it is sent a termination signal.


Sending Signals to Processes with kill

The kill command is used to send signals to programs. Its most common syntax looks like this:

$ kill -signal PID…

If no signal is specified on the command line, then the TERM (terminate) signal is sent by default. The kill command is most often used to send the signals listed here:


Number

Name

Meaning

1

HUP

Hang up. This is a vestige of the good old days when terminals were attached to remote computers with phone lines and modems. The signal is used to indicate to programs that the controlling terminal has “hung up.” The effect of this signal can be demonstrated by closing a terminal session. The foreground program running on the terminal will be sent the signal and will terminate.

This signal is also used by many daemon programs to cause a reinitialization. This means that when a daemon is sent this signal, it will restart and reread its configuration file. The Apache web server is an example of a daemon that uses the HUP signal in this way.

2

INT

Interrupt. This performs the same function as ctrl-C sent from the terminal. It will usually terminate a program.

3

QUIT

Quit.

9

KILL

Kill. This signal is special. Whereas programs may choose to handle signals sent to them in different ways, including ignoring them all together, the KILL signal is never actually sent to the target program. Rather, the kernel immediately terminates the process. When a process is terminated in this manner, it is given no opportunity to “clean up” after itself or save its work. For this reason, the KILL signal should be used only as a last resort when other termination signals fail.

11

SEGV

Segmentation violation. This signal is sent if a program makes illegal use of memory; that is, if it tried to write somewhere it was not allowed to write.

15

TERM

Terminate. This is the default signal sent by the kill command. If a program is still “alive” enough to receive signals, it will terminate.

18

CONT

Continue. This will restore a process after a STOP or TSTP signal. This signal is sent by the bg and fg commands.

19

STOP

Stop. This signal causes a process to pause without terminating. Like the KILL signal, it is not sent to the target process, and thus it cannot be ignored.

20

TSTP

Terminal stop. This is the signal sent by the terminal when ctrl-Z is pressed. Unlike the STOP signal, the TSTP signal is received by the program, but the program may choose to ignore it.

28

WINCH

Window change. This is the signal sent by the system when a window changes size. Some programs, such as top and less, will respond to this signal by redrawing themselves to fit the new window dimensions.


For the curious, you can display a complete list of signals with the following command:

$ kill -l

Sending Signals to Multiple Processes with killall

It’s also possible to send signals to multiple processes matching a specified program or username by using the killall command. Here is the syntax:

$ killall [-u user][-signal] name…

Remember, as with kill, you must have superuser privileges to send signals to processes that do not belong to you.


Shutting Down the System

The process of shutting down the system involves the orderly termination of all the processes on the system, as well as performing some vital housekeeping chores (such as syncing all of the mounted file systems) before the system powers off. Four commands can perform this function:

  • halt

  • poweroff

  • reboot

  • shutdown


The first three are pretty self-explanatory and are generally used without any command line options. Here’s an example:

$ sudo reboot

The shutdown command is a bit more interesting. With it, we can specify which of the actions to perform (halt, power down, or reboot) and provide a time delay to the shutdown event. Most often it is used like this to halt the system:

$ sudo shutdown -h now

or like this to reboot the system:

$ sudo shutdown -r now

The delay can be specified in a variety of ways. See the shutdown man page for details. Once the shutdown command is executed, a message is “broadcast” to all logged-in users warning them of the impending event.



Understanding and Managing Linux Processes
Hamed Mohammadi August 13, 2024
Share this post
Archive

Please visit our blog at:

https://zehabsd.com/blog

A platform for Flash Stories:

https://readflashy.com

A platform for Persian Literature Lovers:

https://sarayesokhan.com

Sign in to leave a comment