103.6 Lesson 1
Certificate: |
LPIC-1 |
---|---|
Version: |
5.0 |
Topic: |
103 GNU and Unix Commands |
Objective: |
103.6 Modify process execution priorities |
Lesson: |
1 of 1 |
Introduction
Operating systems able to run more than one process at the same time are called multi-tasking or multi-processing systems. Whilst true simultaneity only happens when more than one processing unit is available, even single processor systems can mimic simultaneity by switching between processes very quickly. This technique is also employed in systems with many equivalent CPUs, or symmetric multi-processor (SMP) systems, given that the number of potential concurrent processes greatly exceeds the number of available processor units.
In fact, only one process at a time can control the CPU. However, most process activities are system calls, that is, the running process transfers CPU control to an operating system’s process so it performs the requested operation. System calls are in charge of all inter-device communication, like memory allocations, reading and writing on filesystems, printing text on the screen, user interaction, network transfers, etc. Transferring CPU control during a system call allows the operating system to decide whether to return CPU control to the previous process or to hand it to another process. As modern CPUs can execute instructions much faster than most external hardware can communicate with each other, a new controlling process can do a lot of CPU work while previously requested hardware responses are still unavailable. To ensure maximum CPU harnessing, multi-processing operating systems keep a dynamic queue of active processes waiting for a CPU time slot.
Although they allow to significantly improve CPU time utilization, relying solely on system calls to switch between processes is not enough to achieve satisfactory multi-tasking performance. A process that makes no system calls could control the CPU indefinitely. This is why modern operating systems are also preemptive, that is, a running process can be put back in the queue so a more important process can control the CPU, even if the running process has not made a system call.
The Linux Scheduler
Linux, as a preemptive multi-processing operating system, implements a scheduler that organizes the process queue. More precisely, the scheduler also decides which queued thread will be executed — a process can branch out many independent threads — but process and thread are interchangeable terms in this context. Every process has two predicates that intervene on its scheduling: the scheduling policy and the scheduling priority.
There are two main types of scheduling policies: real-time policies and normal policies. Processes under a real-time policy are scheduled by their priority values directly. If a more important process becomes ready to run, a less important running process is preempted and the higher priority process takes control of the CPU. A lower priority process will gain CPU control only if higher priority processes are idle or waiting for hardware response.
Any real-time process has higher priority than a normal process. As a general purpose operating system, Linux runs just a few real-time processes. Most processes, including system and user programs, run under normal scheduling policies. Normal processes usually have the same priority value, but normal policies can define execution priority rules using another process predicate: the nice value. To avoid confusion with the dynamic priorities derived from nice values, scheduling priorities are usually called static scheduling priorities.
The Linux scheduler can be configured in many different ways and even more intricate ways of establishing priorities exist, but these general concepts always apply. When inspecting and tuning process scheduling, it is important to keep in mind that only processes under normal scheduling policy will be affected.
Reading Priorities
Linux reserves static priorities ranging from 0 to 99 for real-time processes and normal processes are assigned to static priorities ranging from 100 to 139, meaning that there are 39 different priority levels for normal processes. Lower values mean higher priority. The static priority of an active process can be found in the sched
file, located in its respective directory inside the /proc
filesystem:
$ grep ^prio /proc/1/sched prio : 120
As shown in the example, the line beginning with prio
gives the priority value of the process (the PID 1 process is the init or the systemd process, the first process the kernel starts during system initialization). The standard priority for normal processes is 120, so that it can be decreased to 100 or increased to 139. The priorities of all running process can be verified with the command ps -Al
or ps -el
:
$ ps -el F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 0 1 0 0 80 0 - 9292 - ? 00:00:00 systemd 4 S 0 19 1 0 80 0 - 8817 - ? 00:00:00 systemd-journal 4 S 104 61 1 0 80 0 - 64097 - ? 00:00:00 rsyslogd 4 S 0 63 1 0 80 0 - 7244 - ? 00:00:00 cron 1 S 0 126 1 0 80 0 - 4031 - ? 00:00:00 dhclient 4 S 0 154 1 0 80 0 - 3937 - pts/0 00:00:00 agetty 4 S 0 155 1 0 80 0 - 3937 - pts/1 00:00:00 agetty 4 S 0 156 1 0 80 0 - 3937 - pts/2 00:00:00 agetty 4 S 0 157 1 0 80 0 - 3937 - pts/3 00:00:00 agetty 4 S 0 158 1 0 80 0 - 3937 - console 00:00:00 agetty 4 S 0 160 1 0 80 0 - 16377 - ? 00:00:00 sshd 4 S 0 280 0 0 80 0 - 5301 - ? 00:00:00 bash 0 R 0 392 280 0 80 0 - 7221 - ? 00:00:00 ps
The PRI
column indicates the static priority assigned by the kernel. Note, however, that the priority value displayed by ps
differs from that obtained in the previous example. Due to historical reasons, priorities displayed by ps
range from -40 to 99 by default, so the actual priority is obtained by adding 40 to it (in particular, 80 + 40 = 120).
It is also possible to continuously monitor processes currently being managed by the Linux kernel with program top
. As with ps
, top
also displays the priority value differently. To make it easier to identify real-time processes, top
subtracts the priority value by 100, thus making all real-time priorities negative, with a negative number or rt identifying them. Therefore, normal priorities displayed by top
range from 0 to 39.
Note
|
To get more details from the $ ps -e -o user,uid,comm,tty,pid,ppid,pri,pmem,pcpu --sort=-pcpu | head |
Process Niceness
Every normal process begins with a default nice value of 0 (priority 120). The nice name comes from the idea that “nicer” processes allow other processes to run before them in a particular execution queue. Nice numbers range from -20 (less nice, high priority) to 19 (more nice, low priority). Linux also allows the ability to assign different nice values to threads within the same process. The NI
column in ps
output indicates the nice number.
Only the root user can decrease the niceness of a process below zero. It’s possible to start a process with a non-standard priority with the command nice
. By default, nice
changes the niceness to 10, but it can be specified with option -n
:
$ nice -n 15 tar czf home_backup.tar.gz /home
In this example, the command tar
is executed with a niceness of 15. The command renice
can be used to change the priority of a running process. The option -p
indicates the PID number of the target process. For example:
# renice -10 -p 2164 2164 (process ID) old priority 0, new priority -10
The options -g
and -u
are used to modify all the processes of a specific group or user, respectively. With renice +5 -g users
, the niceness of processes owned by users of the group users will be raised in five.
Besides renice
, the priority of processes can be modified with other programs, like the program top
. On the top main screen, the niceness of a process can be modified by pressing r
and then the PID number of the process:
top - 11:55:21 up 23:38, 1 user, load average: 0,10, 0,04, 0,05 Tasks: 20 total, 1 running, 19 sleeping, 0 stopped, 0 zombie %Cpu(s): 0,5 us, 0,3 sy, 0,0 ni, 99,0 id, 0,0 wa, 0,2 hi, 0,0 si, 0,0 st KiB Mem : 4035808 total, 774700 free, 1612600 used, 1648508 buff/cache KiB Swap: 7999828 total, 7738780 free, 261048 used. 2006688 avail Mem PID to renice [default pid = 1] PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 74232 7904 6416 S 0,000 0,196 0:00.12 systemd 15 root 20 0 67436 6144 5568 S 0,000 0,152 0:00.03 systemd-journal 21 root 20 0 61552 5628 5000 S 0,000 0,139 0:00.01 systemd-logind 22 message+ 20 0 43540 4072 3620 S 0,000 0,101 0:00.03 dbus-daemon 23 root 20 0 45652 6204 4992 S 0,000 0,154 0:00.06 wickedd-dhcp4 24 root 20 0 45648 6276 5068 S 0,000 0,156 0:00.06 wickedd-auto4 25 root 20 0 45648 6272 5060 S 0,000 0,155 0:00.06 wickedd-dhcp6
The message PID to renice [default pid = 1]
appears with the first listed process selected by default. To change the priority of another process, type its PID and press Enter. Then, the message Renice PID 1 to value
will appear (with the requested PID number) and a new nice value can be assigned.
Guided Exercises
-
In a preemptive multi-tasking system, what happens when a lower priority process is occupying the processor and a higher priority process is queued to be executed?
-
Consider the following
top
screen:top - 08:43:14 up 23 days, 12:29, 5 users, load average: 0,13, 0,18, 0,21 Tasks: 240 total, 2 running, 238 sleeping, 0 stopped, 0 zombie %Cpu(s): 1,4 us, 0,4 sy, 0,0 ni, 98,1 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st MiB Mem : 7726,4 total, 590,9 free, 1600,8 used, 5534,7 buff/cache MiB Swap: 30517,0 total, 30462,5 free, 54,5 used. 5769,4 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 171420 10668 7612 S 0,0 0,1 9:59.15 systemd 2 root 20 0 0 0 0 S 0,0 0,0 0:02.76 kthreadd 3 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 rcu_gp 4 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 rcu_par_gp 8 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 mm_percpu_wq 9 root 20 0 0 0 0 S 0,0 0,0 0:49.06 ksoftirqd/0 10 root 20 0 0 0 0 I 0,0 0,0 18:24.20 rcu_sched 11 root 20 0 0 0 0 I 0,0 0,0 0:00.00 rcu_bh 12 root rt 0 0 0 0 S 0,0 0,0 0:08.17 migration/0 14 root 20 0 0 0 0 S 0,0 0,0 0:00.00 cpuhp/0 15 root 20 0 0 0 0 S 0,0 0,0 0:00.00 cpuhp/1 16 root rt 0 0 0 0 S 0,0 0,0 0:11.79 migration/1 17 root 20 0 0 0 0 S 0,0 0,0 0:26.01 ksoftirqd/1
What PIDs have real-time priorities?
-
Consider the following
ps -el
listing:F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 0 1 0 0 80 0 - 42855 - ? 00:09:59 systemd 1 S 0 2 0 0 80 0 - 0 - ? 00:00:02 kthreadd 1 I 0 3 2 0 60 -20 - 0 - ? 00:00:00 rcu_gp 1 S 0 9 2 0 80 0 - 0 - ? 00:00:49 ksoftirqd/0 1 I 0 10 2 0 80 0 - 0 - ? 00:18:26 rcu_sched 1 I 0 11 2 0 80 0 - 0 - ? 00:00:00 rcu_bh 1 S 0 12 2 0 -40 - - 0 - ? 00:00:08 migration/0 1 S 0 14 2 0 80 0 - 0 - ? 00:00:00 cpuhp/0 5 S 0 15 2 0 80 0 - 0 - ? 00:00:00 cpuhp/1
Which PID has higher priority?
-
After trying to renice a process with
renice
, the following error happens:$ renice -10 21704 renice: failed to set priority for 21704 (process ID): Permission denied
What is the probable cause for the error?
Explorational Exercises
-
Changing process priorities is usually required when a process is occupying too much CPU time. Using
ps
with standard options for printing all system processes in long format, what--sort
flag will sort processes by CPU utilization, increasing order? -
Command
schedtool
can set all CPU scheduling parameters Linux is capable of or display information for given processes. How can it be used to display the scheduling parameters of process1750
? Also, how canschedtool
be used to change process 1750 to real-time with priority -90 (as displayed bytop
)?
Summary
This lesson covers how Linux shares CPU time among its managed processes. To ensure best performance, more critical processes must overtake less critical processes. The lesson goes through the following steps:
-
Basic concepts about multi-processing systems.
-
What is a process scheduler and how Linux implements it.
-
What are Linux priorities, nice numbers and their purpose.
-
How to read and interpret process priorities in Linux.
-
How to change the priority of a process, before and during its execution.
Answers to Guided Exercises
-
In a preemptive multi-tasking system, what happens when a lower priority process is occupying the processor and a higher priority process is queued to be executed?
The lower priority process pauses and the higher priority process is executed instead.
-
Consider the following
top
screen:top - 08:43:14 up 23 days, 12:29, 5 users, load average: 0,13, 0,18, 0,21 Tasks: 240 total, 2 running, 238 sleeping, 0 stopped, 0 zombie %Cpu(s): 1,4 us, 0,4 sy, 0,0 ni, 98,1 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st MiB Mem : 7726,4 total, 590,9 free, 1600,8 used, 5534,7 buff/cache MiB Swap: 30517,0 total, 30462,5 free, 54,5 used. 5769,4 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 171420 10668 7612 S 0,0 0,1 9:59.15 systemd 2 root 20 0 0 0 0 S 0,0 0,0 0:02.76 kthreadd 3 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 rcu_gp 4 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 rcu_par_gp 8 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 mm_percpu_wq 9 root 20 0 0 0 0 S 0,0 0,0 0:49.06 ksoftirqd/0 10 root 20 0 0 0 0 I 0,0 0,0 18:24.20 rcu_sched 11 root 20 0 0 0 0 I 0,0 0,0 0:00.00 rcu_bh 12 root rt 0 0 0 0 S 0,0 0,0 0:08.17 migration/0 14 root 20 0 0 0 0 S 0,0 0,0 0:00.00 cpuhp/0 15 root 20 0 0 0 0 S 0,0 0,0 0:00.00 cpuhp/1 16 root rt 0 0 0 0 S 0,0 0,0 0:11.79 migration/1 17 root 20 0 0 0 0 S 0,0 0,0 0:26.01 ksoftirqd/1
What PIDs have real-time priorities?
PIDs 12 and 16.
-
Consider the following
ps -el
listing:F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 0 1 0 0 80 0 - 42855 - ? 00:09:59 systemd 1 S 0 2 0 0 80 0 - 0 - ? 00:00:02 kthreadd 1 I 0 3 2 0 60 -20 - 0 - ? 00:00:00 rcu_gp 1 S 0 9 2 0 80 0 - 0 - ? 00:00:49 ksoftirqd/0 1 I 0 10 2 0 80 0 - 0 - ? 00:18:26 rcu_sched 1 I 0 11 2 0 80 0 - 0 - ? 00:00:00 rcu_bh 1 S 0 12 2 0 -40 - - 0 - ? 00:00:08 migration/0 1 S 0 14 2 0 80 0 - 0 - ? 00:00:00 cpuhp/0 5 S 0 15 2 0 80 0 - 0 - ? 00:00:00 cpuhp/1
Which PID has higher priority?
PID 12.
-
After trying to renice a process with
renice
, the following error happens:$ renice -10 21704 renice: failed to set priority for 21704 (process ID): Permission denied
What is the probable cause for the error?
Only user root can decrease nice numbers below zero.
Answers to Explorational Exercises
-
Changing process priorities is usually required when a process is occupying too much CPU time. Using
ps
with standard options for printing all system processes in long format, what--sort
flag will sort processes by CPU utilization, increasing order?$ ps -el --sort=pcpu
-
Command
schedtool
can set all CPU scheduling parameters Linux is capable of or display information for given processes. How can it be used to display the scheduling parameters of process1750
? Also, how canschedtool
be used to change process 1750 to real-time with priority -90 (as displayed bytop
)?$ schedtool 1750
$ schedtool -R -p 89 1750