进程的优先级 与 CFS 进程调度
在Linux下改变进程的优先级
作者:曾老师,华清远见嵌入式学院讲师。 作为多任务的操作系统,Linux内核为每个创建的进程分配时间片并根据其优先级进行调度。当进程被创建时,其对应的task_struct里包含了四个优先级:
struct task_struct {
……
int prio, static_prio, normal_prio;
unsigned int rt_priority;
……
};
在内核头文件include/linux/sched.h中定义了如下宏
#define MAX_USER_RT_PRIO 100
#define MAX_RT_PRIO MAX_USER_RT_PRIO //100
#define MAX_PRIO (MAX_RT_PRIO + 40) //140
内核中规定进程的优先级范围为[, MAX_PRIO-]
实时任务的优先级范围是[, MAX_RT_PRIO-] //[0,99]
非实时任务的优先级范围是[MAX_RT_PRIO, MAX_PRIO-] //[100,139] 优先级值越小,意味着级别越高,任务先被内核调度。
那任务的优先级又是如何确定的呢?和task_struct中的成员是什么关系?
① prio指的是任务当前的动态优先级,其值影响任务的调度顺序。
② normal_prio指的是任务的常规优先级,该值基于static_prio和调度策略计算。
③ static_prio指的是任务的静态优先级,在进程创建时分配,该值会影响分配给任务的时间片的长短和非实时任务动态优先级的计算。
④ rt_priority指的是任务的实时优先级。若为0表示是非实时任务,[, ]表示实时任务,值越大,优先级越高。
static_prio = MAX_RT_PRIO + + nice(nice的缺省值是0,范围[, ])
rt_priority缺省值为0,表示非实时任务。[,]表示实时任务
对于实时任务,prio = normal_prio = static_prio
对于非实时任务 prio = normal_prio = MAX_RT_PRIO – – rt_priority
prio的值在使用实时互斥量时会暂时提升,释放后恢复成normal_prio 下面来了解一下如何在应用程序中改变进程的优先级。
#include <sys/time.h>
#include <sys/resource.h>
int setpriority(int which, int who, int prio);
//该函数可以修改进程、进程组或用户所有进程的nice值从而影响static_prio
which : PRIO_PROCESS // 修改某个进程
PRIO_PGRP // 修改进程组
PRIO_USER // 修改用户所有进程
who : 进程号(0表示当前调用进程)、进程组号或UID
prio : 新的用户态优先级(即nice值,范围[-,])
返回值 : 执行成功返回0,失败返回-1并设置errno if (setpriority(PRO_PROCESS, , ) <0)
{
perror(“fail to setpriority”);
exit(-);
} ************************************************************************
#include <sched.h>
int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param);
struct sched_param
{
int __sched_priority;
};
// 该函数修改某个进程的调度策略和rt_priority
pid : 要修改的进程号,0表示当前调用进程
policy : 调度策略
SCHED_OTHER(针对非实时进程的调度策略)
SCHED_RR(针对实时进程的轮转调度策略)
SCHED_FIFO(针对实时进程的先进先出调度策略)
param : 指向的结构体中存放着要设置的rt_priority
返回值 : 执行成功返回0,失败返回-1并设置errno
……
struct sched_param sp = {};
if (sched_setscheduler(, SCHED_FIFO, &sp) < )
{
perror(“fail to sched_setscheduler”);
exit(-);
}
linux的线程调度策略,linux将进程分为下面两类
实时进程
¢ 对调度延迟的要求最高,要求立即响应并执行
¢ 调度策略:FIFO、Round Robin
普通进程
Ø交互式进程:间或处于睡眠态,对响应速度要求比较高
Ø批处理进程:在后台执行,能够忍受响应延迟
普通进程调度策略使用CFS,CFS是现在被内核采纳的调度器。它从RSDL/SD中吸取了完全公平的思想,不再跟踪进程的睡眠时间,也不再企图区分交互式进程
CFS算法中,每个进程都有一个“虚拟运行时间”表示该进程运行了“多长时间”,而调度器会选择虚拟运行时间最小的进程来运行
虚拟运行时间的计算与进程实际运行时间成正比,而与进程优先级成反比
CFS以虚拟运行时间作为键值构造一棵红黑树,从而实现了快速更新和删除完全公平调度Completely Fair Scheduler 核心思想:根据进程的优先级按比例分配运行时间
(公式1)
1.分配给进程的运行时间 = 调度周期 * 进程权重 / 所有进程权重之和
调度周期:将所有处于TASK_RUNNING态进程都调度一遍的时间
CFS对时钟做抽象,引入了虚拟运行时间vruntime的概念,每个进程有自己的vruntime
2.vruntime = 实际运行时间 * NICE_0_LOAD /进程权重
(公式2)
由公式1和2得:
vruntime = (调度周期 * 进程权重/所有进程总权重) * NICE_0_LOAD/进程权重= 调度周期 * NICE_0_LOAD/所有进程总权重
从vruntime的角度,分配给所有进程的时间是一样的
CFS算法,每次选择vruntime最小的进程运行,所有进程的vruntime增长速度宏观上看是同时推进的
CFS 维护了一个以vruntime为顺序的红黑树,可以快速高效地插入或删除任务
调度器每次选择最左侧结点的进程运行,运行结点从树中删除;进程切换时,切换下来的就绪态进程再重新插入树中,
因为换下来的进程一般vruntime比较大所以会靠近树的右侧;总体来说树的内容从右侧迁移到左侧以保持平衡。
进程的优先级 与 CFS 进程调度的更多相关文章
- 二十一、Linux 进程与信号---进程查看和进程状态、进程调度和进程状态变化、进程标识
21.1 进程查看和进程状态 21.1.1 ps 指令 ps 指令通常可以查看到进程的 ID.进程的用户 ID.进程状态和进程的 Command ps:查看当前用户启动的进程 ps -ef:详细查看后 ...
- EPROCESS 进程/线程优先级 句柄表 GDT LDT 页表 《寒江独钓》内核学习笔记(2)
在学习笔记(1)中,我们学习了IRP的数据结构的相关知识,接下来我们继续来学习内核中很重要的另一批数据结构: EPROCESS/KPROCESS/PEB.把它们放到一起是因为这三个数据结构及其外延和w ...
- 第11讲- Android中进程及其优先级
第11讲Android中进程及其优先级 进程与线程: 进程:操作系统结构的基础,资源分配的最小单元,一个操作系统包括多个进程: 线程:线程存在于进程当中,是操作系统调试执行的最小单元,一个进程包括多个 ...
- mfc 进程的优先级
知识点: 进程优先级 获取当前进程句柄 优先级设置 优先级变动 优先级获取 一.进程优先级(优先级等级) 简单的说就是进程(线程)的优先级越高,那么就可以分占相对多的CPU时间片. ...
- 改变进程的优先级,nice,getpriority,setpriority
int getpriority(int which, int who);返回一组进程的优先级 参数which和who确定返回哪一组进程的优先级 The value which is one of PR ...
- RHCE7 管理II-5管理进程的优先级
进程的优先级值称为进程的nice值,共有40种不同的取值(用数字-20到19表示) nice值越大,表示进程的优先级越低. 进程的nice值,只允许root用户来设置负的nice:其他用户只允许设置正 ...
- Linux中进程的优先级
Linux採用两种不同的优先级范围,一种是nice值.还有一种是实时优先级. 1.nice值 nice值得范围是-20~19,默认值是0. 越大的nice值意味着更低的优先级.也就是说nice值为-2 ...
- android中进程的优先级
android中进程的优先级
- Linux基础进程管理优先级
一.进程优先级 Linux进程调度及多任务 每个cpu(或者cpu核心)在一个时间点上只能处理一个进程,通过时间片技术,Linux实际能够运行的进程(和线程数)可以超出实际可用的cpu及核心数量.Li ...
随机推荐
- "System.Web" 中不存在类型或命名空间
System.Web”中不存在类型或命名空间名称script /找不到System.Web.Extensions.dll引用 添加引用就行了...“添加引用→.Net→System.Web.Ente ...
- python基础之元组(Tuple)、字典(Dictionary)详解
元组定义 元组是另一个数据类型,类似于List(列表). 元组用”()”标识.内部元素用逗号隔开.但是元素不能二次赋值,相当于只读列表. 举例: tuple = ( ‘abcd’, 786 , 2.2 ...
- __name__ == '__main__'的作用
当你打开一个.py文件时,经常会在代码的最下面看到if __name__ == '__main__':,现在就来介 绍一下它的作用. 模块是对象,并且所有的模块都有一个内置属性 __name__.一个 ...
- C# Dispose Finalize
比较值得参考的文档:http://www.jb51.net/article/37214.htm. .NET 的内存管理过程: 托管堆假设内存无限大,线性连续分配内存: 实际内存不够使用时,遍历托管堆对 ...
- Start of Something New
Hi Guys This will be the blog of SCaffrey for some time before he creates his own site:) Have a nice ...
- jQuery实现Twitter的自动文字补齐特效
上图效果可以使用jQuery插件Typeahead.js来实现,这款jQuery插件来自于Twitter的一个新的项目,支持远程和本地的数据集.比较有特色的地方在于你可以将数据集使用本地存储(loca ...
- BZOJ 4009 接水果
Description 风见幽香非常喜欢玩一个叫做osu!的游戏,其中她最喜欢玩的模式就是接水果. 由于她已经DT FC了The big black, 她觉得这个游戏太简单了,于是发明了一个更加难的版 ...
- 解决VS2005 VS2008 vs2010断点无效-源代码与原始版本不同
网上说的方法:(额~但是我就是不能用.但是也贴出来) 方法1.直接把整个文件格式化了一次,断点就可以用了Ctrl + A全选菜单:编辑-〉高级-〉设置选定内容的格式 (Ctrl+K, Ctrl+F)通 ...
- oracle的存储过程语法(转)
1.ORA-00942: table or view does not exist 指的你要操作的表尚未存在,需要先create出来先. 2.ORA-00922: missing or invalid ...
- [置顶] linux内核启动2-setup_arch中的内存初始化(目前分析高端内存)
上一篇微博留下了这几个函数,现在我们来分析它们 sanity_check_meminfo(); arm_memblock_init(&meminfo, mdes ...