Linux defines the thread priority range in the header file <linux/sched.h>
/*
* Priority of a process goes from 0..MAX_PRIO-1, valid RT
* priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
* tasks are in the range MAX_RT_PRIO..MAX_PRIO-1. Priority
* values are inverted: lower p->prio value means higher priority.
*
* The MAX_USER_RT_PRIO value allows the actual maximum
* RT priority to be separate from the value exported to
* user-space. This allows kernel threads to set their
* priority to a value higher than any user task. Note:
* MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO.
*/
#define MAX_USER_RT_PRIO 100
#define MAX_RT_PRIO MAX_USER_RT_PRIO
#define MAX_PRIO (MAX_RT_PRIO + 40)
#define DEFAULT_PRIO (MAX_RT_PRIO + 20)
Linux thread scheduling strategy
Linux defines the thread scheduling strategy in the header file <linux/sched.h>
#define SCHED_NORMAL 0
#define SCHED_FIFO 1
#define SCHED_RR 2
#define SCHED_BATCH 3
/* SCHED_ISO: reserved but not implemented yet */
#define SCHED_IDLE 5
-
SCHED_NORMAL is SCHED_OTHER: time-sharing scheduling strategy is adopted.
-
SCHED_FIFO: The real-time scheduling strategy is adopted, and it is first-come-first-served, and it keeps running until a higher priority task arrives or gives up by itself.
-
SCHED_RR: The real-time scheduling strategy is adopted, and the time slice is rotated. When the time slice is used up, the system will re-allocate the time slice and put it at the end of the ready queue.
-
SCHED_BATCH: For batch processing.
-
SCHED_IDLE: Processes using this scheduler have the lowest priority. Introduced when implementing CFS.
Check the thread priority under the shell
-
top command
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 2804 1576 1192 S 0.0 0.3 0:00.97 init
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root RT 0 0 0 0 S 0.0 0.0 0:00.00 migration/0
4 root 20 0 0 0 0 S 0.0 0.0 0:00.02 ksoftirqd/0
5 root RT 0 0 0 0 S 0.0 0.0 0:00.00 watchdog/0
6 root 20 0 0 0 0 S 0.0 0.0 0:00.06 events/0
PR is the thread priority, the range is [0, 40), and the thread with real-time priority is displayed as RT. The smaller the value, the higher the priority. NI is the Nice value, range [-20, 20), and the PR value is the initial thread priority plus the Nice value. Both PR and NI values are read from the proc file system "/proc/[pid]/stat"
cat /proc/1/stat
1 (init) S 0 1 1 0 -1 4202752 4680 154640 23 343 6 136 154 151 20 0 ...
cat /proc/3/stat
3 (migration/0) S 2 0 0 0 -1 2216730688 0 0 0 0 0 0 0 0 -100 0 ...
The description of items 18 and 19 of stat through man proc is as follows
priority %ld
(18) (Explanation for Linux 2.6) For processes running a real-time scheduling policy (policy below; see sched_setscheduler(2)),
this is the negated scheduling priority, minus one; that is, a number in the range -2 to -100, corresponding to real-time priorities 1 to 99.
For processes running under a non-real-time scheduling policy, this is the raw nice value (setpriority(2)) as represented in the kernel.
The kernel stores nice values as numbers in the range 0 (high) to 39 (low), corresponding to the user-visible nice range of -20 to 19.
Before Linux 2.6, this was a scaled value based on the scheduler weighting given to this process.
nice %ld
(19) The nice value (see setpriority(2)), a value in the range 19 (low priority) to -20 (high priority).
-
ps command
c@c-desktop:~$ ps -el
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 1 0 0 80 0 - 702 poll_s ? 00:00:01 init
1 S 0 2 0 0 80 0 - 0 kthrea ? 00:00:00 kthreadd
1 S 0 3 2 0 -40 - - 0 migrat ? 00:00:00 migration/0
1 S 0 4 2 0 80 0 - 0 ksofti ? 00:00:00 ksoftirqd/0
5 S 0 5 2 0 -40 - - 0 watchd ? 00:00:00 watchdog/0
1 S 0 6 2 0 80 0 - 0 worker ? 00:00:00 events/0
Why is the PRI here different from the PR of top? I found the reason by looking at the source code of procps
In linux procps, the column labeled "PRI" in ps -l is -o opri
c@c-desktop:~$ ps -e -o pid,pri,opri,intpri,priority,ni,cmd
PID PRI PRI PRI PRI NI CMD
1 19 80 80 20 0 /sbin/init
2 19 80 80 20 0 [kthreadd]
3 139 -40 -40 -100 - [migration/0]
4 19 80 80 20 0 [ksoftirqd/0]
5 139 -40 -40 -100 - [watchdog/0]
6 19 80 80 20 0 [events/0]
procps/output.c contains specific instructions
// "priority" (was -20..20, now -100..39)
// "intpri" and "opri" (was 39..79, now -40..99)
// "pri_foo" -- match up w/ nice values of sleeping processes (-120..19)
// "pri_bar" -- makes RT pri show as negative (-99..40)
// "pri_baz" -- the kernel's ->prio value, as of Linux 2.6.8 (1..140)
// "pri" (was 20..60, now 0..139)
// "pri_api" -- match up w/ RT API (-40..99)
Modify thread priority under the shell
-
nice command
The nice command can specify the Nice value when the thread is loaded to change the thread priority. nice -n [priority] [command] When the input priority exceeds 19, it takes 19, and when it is less than -20, it takes -20.
root@c-desktop:~/Code# nice -n -20 ./a.out &
root@c-desktop:~/Code# ps -o pid,priority,ni,cmd
PID PRI NI CMD
2138 0 -20 ./a.out
root@c-desktop:~/Code# nice -n 19 ./a.out &
root@c-desktop:~/Code# ps -o pid,priority,ni,cmd
PID PRI NI CMD
2145 39 19 ./a.out
-
renice command
The renice command can change the Nice value of a running thread, and then change the priority of the thread. renice -n [priority] -p [pid] When the priority of the input exceeds 19, it takes 19, and when it is less than -20, it takes -20.
root@c-desktop:~/Code# ps -o pid,priority,ni,cmd
PID PRI NI CMD
2145 39 19 ./a.out
root@c-desktop:~/Code# renice -n -20 -p 2145
2145: old priority 19, new priority -20
root@c-desktop:~/Code# ps -o pid,priority,ni,cmd
PID PRI NI CMD
2145 0 -20 ./a.out