Linux Learning Chapter 6: Managing Running Processes

📢 This article was translated by gemini-3-flash-preview

Chapter 6: Managing Running Processes

Linux is a multi-user, multi-tasking operating system. Multi-tasking means multiple programs can run simultaneously. An instance of a running program is called a process.

You can start, pause, stop, or kill processes via the shell. You can also move processes to the background or bring them to the foreground.

6.1 Understanding Processes

A process is a running instance of a command. Every process in the system is identified by a Process ID (PID), which is unique to the current system. Besides the PID, a process is associated with a specific user account and group, which determines the system resources the process can access.

Commands used to display process information primarily pull raw data from the /proc file system. Each process stores its information in a subdirectory within /proc named after its PID.

6.2 Listing Processes

Use the ps command or the top command. The top command provides a more screen-oriented way to list processes.

6.2.1 Using the ps Command

Using ps u displays the username and other detailed information.

VSZ: Virtual Set Size. Shows the size of the process image in KB.

RSS: Resident Set Size. Shows the size of the program in physical memory.

VSZ is the amount of memory allocated to the process, while RSS is the amount of memory the process is actually using (representing physical memory that cannot be swapped).

STAT column: S indicates a sleeping process, R indicates a running process, and + indicates the process is associated with a foreground operation.

View all processes for the current user: ps ux | less

View processes for all users: ps aux | less

You can also customize the output columns and sort them. For example:

1
ps -eo pid,user,uid,group,gid,vsz,rss,comm --sort=-vsz | less

-e displays every running process, -o specifies the columns to display (where comm is the command name), and --sort=-vsz sorts by the VSZ column in descending order.

6.2.2 Using the top Command

The top command defaults to displaying processes sorted by current CPU usage percentage.

Operations within the top command:

CommandDescription
hHelp
MSort by memory usage
1Toggle display of all CPU usage (for multi-CPU systems)
RReverse sort order
uEnter a username to show only that user’s processes
rChange process priority (nice value)
kKill a process (kill command)

6.2.3 Using System Monitor

A GUI tool for the GNOME desktop.

6.3 Managing Background and Foreground Processes

On systems without a GUI, you must use the shell for all operations. Although the Bash shell doesn’t have a GUI to manage programs, you can move active programs between the foreground and background. This allows you to run many programs and switch to the one you need to handle.

6.3.1 Starting Background Processes

To put a command in the background:

  1. Append an & to the end of the command.

  2. Use the at command to run commands later.

  3. For a running process, press Ctrl+Z to stop it, then type fg to bring it to the foreground or bg to start it running in the background.

To prevent background output from cluttering your foreground work, redirect it to the null device: 2>/dev/null.

Use the jobs command to view background jobs (use -l to see PIDs). A + next to a job number indicates the most recent background job, while - indicates the job placed in the background just before the most recent one.

6.3.2 Using Foreground and Background Commands

To reference a background job, use % followed by the job number (from the jobs output). Other ways to reference jobs:

  • % — References the most recent background job (the one with the +).

  • %string — Job starting with “string” (must be unique).

  • %?string — Job containing “string” anywhere in the command line (must be unique).

  • %-- — References the job placed in the background before the most recent one (the one with the -).

Use fg %1 to bring job #1 to the foreground. Use bg %5 to resume a stopped job #5 in the background.

Note: The vi command stops automatically when moved to the background. Remember to save your file before backgrounding it to avoid data loss.

6.4 Killing and Modifying Processes

You can send different signals to a process to change its behavior or modify its processor priority.

6.4.1 Using kill and killall

While these commands are often used to terminate a process, they actually send signals. Signals are represented by numbers or names.

SignalNumberDescription
SIGHUP1Reread configuration files
SIGINT2Interrupt via keyboard (Ctrl+C)
SIGQUIT3Quit via keyboard
SIGABRT6Abort signal generated by abort(3)
SIGKILL9Kill signal (cannot be ignored)
SIGTERM15Termination signal (default)
SIGCONT19, 18, 25Continue a stopped process
SIGSTOP17, 19, 23Stop a process

For the last two signals, the first value applies to Alpha and SPARC, the middle to x86, and the last to MIPS architectures.

The default is the SIGTERM (15) signal. While processes can handle or ignore various signals, no process can block SIGKILL (9) or SIGSTOP.

  1. Using kill to send a signal via PID:
1
kill [signal] [PID]

Example: Killing process 2333: kill -9 2333 or kill -SIGKILL 2333.

  1. Using killall to send a signal by name:

Useful for killing multiple processes with the same name, but be careful not to kill essential processes accidentally.

Example: Restarting gnome-shell: killall -1 gnome-shell

6.4.2 Setting Processor Priority with nice and renice

When the Linux kernel decides which process gets CPU time, it considers the “nice” value, ranging from -20 to 19. The default is 0.

A lower nice value means higher priority. Only the root user can set negative values (increase priority). Normal users can only increase the nice value (decrease priority).

Use the nice command to start a process with a specific priority, or renice to change the priority of an already running process by PID.

nice -n +5 updatedb & runs the updatedb command in the background with a priority offset of +5.

renice -n 3 2333 changes the nice value of PID 2333 to 3.

6.5 Limiting Processes with cgroups

A nice value set for a process does not necessarily apply to its child processes. In other words, nice cannot limit the total amount of system resources a specific user or application can use.

You can use cgroups (control groups) to define a process as a “task” within a specific control group. You can set up tasks in a hierarchy, including “daemon” tasks (setting default limits for background servers) and sub-tasks with specific limits for things like httpd or vsftpd.

When a task starts a process, the child process inherits the parent’s limits. These limits can cover storage, processor scheduling, process reporting, CPU allocation, device access, and memory usage.

Configuring cgroups can be complex, involving editing /etc/cgconfig.conf to create groups or /etc/cgrules.conf to limit specific users/groups. You can use the cgcreate command to add groups to the /sys/fs/cgroup hierarchy. Warning: incorrect settings may prevent the system from booting.