mirror of
https://github.com/gatieme/LDD-LinuxDeviceDrivers.git
synced 2026-09-22 12:43:39 +08:00
进程调度之优先级详解...
This commit is contained in:
@@ -124,9 +124,12 @@ linux把进程区分为实时进程和非实时进程, 其中非实时进程进
|
||||
这需要与CPU的紧密交互. 每个进程刚好属于某一调度类, 各个调度类负责管理所属的进程. 通用调度器自身不涉及进程管理, 其工作都委托给调度器类.
|
||||
|
||||
|
||||
#优先级的内核表示
|
||||
##优先级的内核表示
|
||||
-------
|
||||
|
||||
|
||||
**linux优先级概述**
|
||||
|
||||
>在用户空间通过nice命令设置进程的静态优先级, 这在内部会调用nice系统调用, 进程的nice值在-20~+19之间. 值越低优先级越高.
|
||||
>
|
||||
>setpriority系统调用也可以用来设置进程的优先级. 它不仅能够修改单个线程的优先级, 还能修改进程组中所有进程的优先级, 或者通过制定UID来修改特定用户的所有进程的优先级
|
||||
@@ -147,6 +150,10 @@ linux把进程区分为实时进程和非实时进程, 其中非实时进程进
|
||||

|
||||
|
||||
|
||||
**内核的优先级表示**
|
||||
|
||||
内核表示优先级的所有信息基本都放在[include/linux/sched/prio.h](http://lxr.free-electrons.com/source/include/linux/sched/prio.h?v=4.6)中, 其中定义了一些表示优先级的宏和函数,
|
||||
|
||||
优先级数值通过宏来定义, 如下所示,
|
||||
|
||||
其中MAX_NICE和MIN_NICE定义了nice的最大最小值
|
||||
@@ -159,20 +166,11 @@ linux把进程区分为实时进程和非实时进程, 其中非实时进程进
|
||||
#define MIN_NICE -20
|
||||
#define NICE_WIDTH (MAX_NICE - MIN_NICE + 1)
|
||||
|
||||
/* http://lxr.free-electrons.com/source/include/linux/sched/prio.h?v=4.6#L21 */
|
||||
#define MAX_USER_RT_PRIO 100
|
||||
#define MAX_RT_PRIO MAX_USER_RT_PRIO
|
||||
|
||||
/* http://lxr.free-electrons.com/source/include/linux/sched/prio.h?v=4.6#L24 */
|
||||
#define MAX_PRIO (MAX_RT_PRIO + 40)
|
||||
#define DEFAULT_PRIO (MAX_RT_PRIO + 20)
|
||||
```
|
||||
|
||||
此外新版本的内核还引入了EDF实时调度算法, 它的优先级比RT进程和NORMAL/BATCH进程的优先级都要高, 因此内核将MAX_DL_PRIO设置为0, 可以参见内核文件[include/linux/sched/deadline.h](http://lxr.free-electrons.com/source/include/linux/sched/deadline.h)
|
||||
|
||||
```c
|
||||
#define MAX_DL_PRIO 0
|
||||
````
|
||||
|
||||
| 宏 | 值 | 描述 |
|
||||
| ------------- |:-------------:|:-------------:|
|
||||
@@ -186,6 +184,7 @@ linux把进程区分为实时进程和非实时进程, 其中非实时进程进
|
||||
|
||||
而内核提供了一组宏将优先级在各种不同的表示形之间转移
|
||||
|
||||
|
||||
```c
|
||||
// http://lxr.free-electrons.com/source/include/linux/sched/prio.h?v=4.6#L27
|
||||
/*
|
||||
@@ -206,13 +205,43 @@ linux把进程区分为实时进程和非实时进程, 其中非实时进程进
|
||||
#define MAX_USER_PRIO (USER_PRIO(MAX_PRIO))
|
||||
```
|
||||
|
||||
此外也提供了一些EDF调度算法的函数, 如下所示
|
||||
还有一些nice值和rlimit值之间相互转换的函数nice_to_rlimit和rlimit_to_nice, 这在nice系统调用进行检查的时候很有用, 他们定义在[include/linux/sched/prio.h, L47](http://lxr.free-electrons.com/source/include/linux/sched/prio.h#L47)中, 如下所示
|
||||
|
||||
|
||||
```c
|
||||
/*
|
||||
* Convert nice value [19,-20] to rlimit style value [1,40].
|
||||
*/
|
||||
static inline long nice_to_rlimit(long nice)
|
||||
{
|
||||
return (MAX_NICE - nice + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert rlimit style value [1,40] to nice value [-20, 19].
|
||||
*/
|
||||
static inline long rlimit_to_nice(long prio)
|
||||
{
|
||||
return (MAX_NICE - prio + 1);
|
||||
}
|
||||
```
|
||||
|
||||
**DEF最早截至时间优先实时调度算法的优先级描述**
|
||||
|
||||
此外新版本的内核还引入了EDF实时调度算法, 它的优先级比RT进程和NORMAL/BATCH进程的优先级都要高, 关于EDF的优先级的设置信息都早内核头文件[include/linux/sched/deadline.h](http://lxr.free-electrons.com/source/include/linux/sched/deadline.h?v=4.6#L10)
|
||||
|
||||
|
||||
因此内核将MAX_DL_PRIO设置为0, 可以参见内核文件[include/linux/sched/deadline.h](http://lxr.free-electrons.com/source/include/linux/sched/deadline.h?v=4.6#L10)
|
||||
|
||||
```c
|
||||
#define MAX_DL_PRIO 0
|
||||
```
|
||||
|
||||
此外也提供了一些EDF优先级处理所需的函数, 如下所示, 可以参见内核文件[include/linux/sched/deadline.h](http://lxr.free-electrons.com/source/include/linux/sched/deadline.h?v=4.6#L12)
|
||||
|
||||
```c
|
||||
/* 判断一个优先级数值是不是EDF调度算法的优先级 */
|
||||
static inline int dl_prio(int prio)
|
||||
{
|
||||
/* 数组小于MAX_DL_PRIO的优先级就是EDF算法的优先级 */
|
||||
if (unlikely(prio < MAX_DL_PRIO))
|
||||
return 1;
|
||||
return 0;
|
||||
@@ -227,7 +256,7 @@ static inline bool dl_time_before(u64 a, u64 b)
|
||||
{
|
||||
return (s64)(a - b) < 0;
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
|
||||
#进程的优先级表示
|
||||
|
||||
@@ -34,6 +34,9 @@ linux优先级操作的系统调用有nice和getpriority, setpriority
|
||||
##优先级的内核表示
|
||||
-------
|
||||
|
||||
|
||||
**linux优先级概述**
|
||||
|
||||
>在用户空间通过nice命令设置进程的静态优先级, 这在内部会调用nice系统调用, 进程的nice值在-20~+19之间. 值越低优先级越高.
|
||||
>
|
||||
>setpriority系统调用也可以用来设置进程的优先级. 它不仅能够修改单个线程的优先级, 还能修改进程组中所有进程的优先级, 或者通过制定UID来修改特定用户的所有进程的优先级
|
||||
@@ -54,6 +57,10 @@ linux优先级操作的系统调用有nice和getpriority, setpriority
|
||||

|
||||
|
||||
|
||||
**内核的优先级表示**
|
||||
|
||||
内核表示优先级的所有信息基本都放在[include/linux/sched/prio.h](http://lxr.free-electrons.com/source/include/linux/sched/prio.h?v=4.6)中, 其中定义了一些表示优先级的宏和函数,
|
||||
|
||||
优先级数值通过宏来定义, 如下所示,
|
||||
|
||||
其中MAX_NICE和MIN_NICE定义了nice的最大最小值
|
||||
@@ -71,11 +78,6 @@ linux优先级操作的系统调用有nice和getpriority, setpriority
|
||||
#define DEFAULT_PRIO (MAX_RT_PRIO + 20)
|
||||
```
|
||||
|
||||
此外新版本的内核还引入了EDF实时调度算法, 它的优先级比RT进程和NORMAL/BATCH进程的优先级都要高, 因此内核将MAX_DL_PRIO设置为0, 可以参见内核文件[include/linux/sched/deadline.h](http://lxr.free-electrons.com/source/include/linux/sched/deadline.h)
|
||||
|
||||
```c
|
||||
#define MAX_DL_PRIO 0
|
||||
````
|
||||
|
||||
| 宏 | 值 | 描述 |
|
||||
| ------------- |:-------------:|:-------------:|
|
||||
@@ -89,6 +91,7 @@ linux优先级操作的系统调用有nice和getpriority, setpriority
|
||||
|
||||
而内核提供了一组宏将优先级在各种不同的表示形之间转移
|
||||
|
||||
|
||||
```c
|
||||
// http://lxr.free-electrons.com/source/include/linux/sched/prio.h?v=4.6#L27
|
||||
/*
|
||||
@@ -109,9 +112,59 @@ linux优先级操作的系统调用有nice和getpriority, setpriority
|
||||
#define MAX_USER_PRIO (USER_PRIO(MAX_PRIO))
|
||||
```
|
||||
|
||||
此外也提供了一些EDF调度算法的函数, 如下所示, 可以参见内核文件[include/linux/sched/deadline.h](http://lxr.free-electrons.com/source/include/linux/sched/deadline.h)
|
||||
还有一些nice值和rlimit值之间相互转换的函数nice_to_rlimit和rlimit_to_nice, 这在nice系统调用进行检查的时候很有用, 他们定义在[include/linux/sched/prio.h, L47](http://lxr.free-electrons.com/source/include/linux/sched/prio.h#L47)中, 如下所示
|
||||
|
||||
|
||||
```c
|
||||
/*
|
||||
* Convert nice value [19,-20] to rlimit style value [1,40].
|
||||
*/
|
||||
static inline long nice_to_rlimit(long nice)
|
||||
{
|
||||
return (MAX_NICE - nice + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert rlimit style value [1,40] to nice value [-20, 19].
|
||||
*/
|
||||
static inline long rlimit_to_nice(long prio)
|
||||
{
|
||||
return (MAX_NICE - prio + 1);
|
||||
}
|
||||
```
|
||||
|
||||
**DEF最早截至时间优先实时调度算法的优先级描述**
|
||||
|
||||
此外新版本的内核还引入了EDF实时调度算法, 它的优先级比RT进程和NORMAL/BATCH进程的优先级都要高, 关于EDF的优先级的设置信息都早内核头文件[include/linux/sched/deadline.h](http://lxr.free-electrons.com/source/include/linux/sched/deadline.h?v=4.6#L10)
|
||||
|
||||
|
||||
因此内核将MAX_DL_PRIO设置为0, 可以参见内核文件[include/linux/sched/deadline.h](http://lxr.free-electrons.com/source/include/linux/sched/deadline.h?v=4.6#L10)
|
||||
|
||||
```c
|
||||
#define MAX_DL_PRIO 0
|
||||
```
|
||||
|
||||
此外也提供了一些EDF优先级处理所需的函数, 如下所示, 可以参见内核文件[include/linux/sched/deadline.h](http://lxr.free-electrons.com/source/include/linux/sched/deadline.h?v=4.6#L12)
|
||||
|
||||
```c
|
||||
static inline int dl_prio(int prio)
|
||||
{
|
||||
if (unlikely(prio < MAX_DL_PRIO))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int dl_task(struct task_struct *p)
|
||||
{
|
||||
return dl_prio(p->prio);
|
||||
}
|
||||
|
||||
static inline bool dl_time_before(u64 a, u64 b)
|
||||
{
|
||||
return (s64)(a - b) < 0;
|
||||
}
|
||||
````
|
||||
|
||||
##进程的优先级表示
|
||||
-------
|
||||
|
||||
@@ -384,6 +437,24 @@ clamp_val宏定义在[include/linux/kernel.h, L757](http://lxr.free-electrons.co
|
||||
##can_nice
|
||||
-------
|
||||
|
||||
can_nice可检查有没有nice的权限, 该函数定义在[kernel/sched/core.c, #L3544](http://lxr.free-electrons.com/source/kernel/sched/core.c?v=4.6#L3544)中, 如下所示
|
||||
|
||||
```c
|
||||
/*
|
||||
* can_nice - check if a task can reduce its nice value
|
||||
* @p: task
|
||||
* @nice: nice value
|
||||
*/
|
||||
int can_nice(const struct task_struct *p, const int nice)
|
||||
{
|
||||
/* convert nice value [19,-20] to rlimit style value [1,40] */
|
||||
int nice_rlim = nice_to_rlimit(nice);
|
||||
|
||||
return (nice_rlim <= task_rlimit(p, RLIMIT_NICE) ||
|
||||
capable(CAP_SYS_NICE));
|
||||
}
|
||||
```
|
||||
|
||||
##security_task_setnice
|
||||
-------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user