LINUX进程调度分析源码,Linux 实时调度(源码分析)
为了弄清楚在多cpu系统中是如何实现实时调度的,先引入以下几个概念:
cpu的状态:
我们知道,在linux系统中,任务的优先级为0~140。
INVALID:(-1)该cpu不可用
IDLE(0):140
NORMAL(1):100~139对应于普通任务的优先级
RT0~RT99(2~102):对应于实时任务的优先级
进程优先级:
在linux内核中,每个进程都有一个task_struct,其中与优先级相关的属性包括
1、prio:对于非实时进程而言prio==normal_prio=99-rt_priority(prio的值越大,则进程的优先级越小)
2、normal_prio:99-rt_priority
3、static_prio:=100+nice
4、rt_priority:0:非实时任务;[1,99]实时任务,值越大,优先级越高。
在调度时使用了prio,其数值0对应最高优先级,99为最低实时优先级。Prio和normal_prio数值越大优先级越小,而rt_priority的数值越大优先级越大。
task balance:
在多cpu系统中,为了保证各个cpu上实时任务的负载均衡,引入了push和pull操作:
1、push操作:
当当前cpu上有多于一个的实时任务,那么需要使用pull操作看看是否可以将还未运行的实时任务移动到其他的cpu上,主要操作由push_rt_task函数完成。static int push_rt_task(struct rq *rq)
{
struct task_struct *next_task;
struct rq *lowest_rq;
int ret = 0;
///如果当前队列不是超载状态,则直接返回
if (!rq->rt.overloaded)
return 0;
///选择rq中下一个进程
next_task = pick_next_pushable_task(rq);
if (!next_task)
return 0;
retry:
......
///如果下一个进程的优先级比当前进程的优先级高,那么需要执行的不是push操作而是重新调度
if (unlikely(next_task->prio curr->prio)) {
resched_task(rq->curr);
return 0;
}
......
///寻找那个cpu的rq符合条件,将其rq上锁
lowest_rq = find_lock_lowest_rq(next_task, rq);
///如果没有找到合适的rq,我们则需要判断:到底还要不要再找,因为在find_lock_lowest_rq函数中释放了当前rq上的锁,因此可能会导致当前rq上没有需要push的任务,在这种情况下我们就不用再试,如果需要push的任务还在,那么则进入retry继续尝试。
if (!lowest_rq) {
struct task_struct *task;
task = pick_next_pushable_task(rq);
if (task_cpu(next_task) == rq->cpu && task == next_task) {
goto out;
}
if (!task)
goto out;
put_task_struct(next_task);
next_task = task;
goto retry;
}
///执行任务迁移相关的工作。
deactivate_task(rq, next_task, 0);
set_task_cpu(next_task, lowest_rq->cpu);
activate_task(lowest_rq, next_task, 0);
ret = 1;
resched_task(lowest_rq->curr);
double_unlock_balance(rq, lowest_rq);
out:
put_task_struct(next_task);
return ret;
}
2、pull操作
与push操作相反,pull操作用于当前cpu的rq比较空闲,想要主动调入实时任务,该操作主要由
pull_rt_task完成。static int pull_rt_task(struct rq *this_rq)
{
int this_cpu = this_rq->cpu, ret = 0, cpu;
struct task_struct *p;
struct rq *src_rq;
if (likely(!rt_overloaded(this_rq)))
return 0;
///查找每一个超载的cpu
for_each_cpu(cpu, this_rq->rd->rto_mask) {
......
///src_rq:需要pull的cpu。
src_rq = cpu_rq(cpu);
///如果src_rq的下一个任务的优先级高于当前cpu的优先级,则什么都不用做,因为src_cpu会主动执行pull操作。
if (src_rq->rt.highest_prio.next >=
this_rq->rt.highest_prio.curr)
continue;
double_lock_balance(this_rq, src_rq);
///判断是否有需要被pull的任务,没有则退出
if (src_rq->rt.rt_nr_running <= 1)
goto skip;
///找到src_rq上最高优先级的任务
p = pick_next_highest_task_rt(src_rq, this_cpu);
if (p && (p->prio rt.highest_prio.curr)) {
WARN_ON(p == src_rq->curr);
WARN_ON(!p->on_rq);
if (p->prio curr->prio)
goto skip;
ret = 1;
deactivate_task(src_rq, p, 0);
set_task_cpu(p, this_cpu);
activate_task(this_rq, p, 0);
}
skip:
double_unlock_balance(this_rq, src_rq);
}
return ret;
}
LINUX进程调度分析源码,Linux 实时调度(源码分析)相关推荐
- 【Linux 内核】实时调度类 ① ( 进程分类 | 实时进程、普通进程 | Linux 内核 SCHED_FIFO、SCHED_RR 调度策略 | 实时调度实体 sched_rt_entity )
文章目录 一.进程分类 ( 实时进程 | 普通进程 ) 二.Linux 内核调度策略 1.SCHED_FIFO 调度策略 2.SCHED_RR 调度策略 三.实时调度实体 sched_rt_entit ...
- arm linux 进程调度,详解ARM Linux 2.4.x进程调度
Linux2.4.x是一个基于非抢占式的多任务的分时操作系统,虽然在用户进程的调度上采用抢占式策略,但是而在内核还是采用了轮转的方法,如果有个内核态的线程恶性占有CPU不释放,那系统无法从中解脱出来, ...
- linux 进程调度ppt,第章 Linux进程调度.ppt
第章 Linux进程调度 * * SCHED_FIFO 与 SCHED_RR 的区别是: 当进程的调度策略为前者时,当前实时进程将一直占用 CPU 直至自动退出,除非有更紧迫的. 优先级更高的实时进程 ...
- linux进程调度采取的是,Linux进程调度
进程状态 进程调度就是让进程从一种状态切换到另一种状态.Linux中进程的主要状态如下, 值 状态 缩写 含义 0 TASK_RUNNING R 正在运行或可运行 1 TASK_INTERRUPTIB ...
- 【Linux 内核】实时调度类 ② ( 实时调度实体 sched_rt_entity 源码分析 | run_list、timeout、watchdog_stamp、time_slice 字段 )
文章目录 一.sched_rt_entity 源码分析 1.run_list 字段 2.timeout 字段 3.watchdog_stamp 字段 4.time_slice 字段 5.back 字段 ...
- Linux进程调度 - 实时调度器 LoyenWang
背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...
- Linux进程管理 (9)实时调度类分析,以及FIFO和RR对比实验
关键词:rt_sched_class.SCHED_FIFO.SCHED_RR.sched_setscheduler().sched_setaffinity().RR_TIMESLICE. 本文主要关注 ...
- Linux进程调度器概述--Linux进程的管理与调度(十五)
日期 内核版本 架构 作者 GitHub CSDN 2016-06-14 Linux-4.6 X86 & arm gatieme LinuxDeviceDrivers Linux进程管理与调度 ...
- linux操作的进程调度没有采用,Linux进程调度分析
Computer Knowledge and Technology 电脑知识 与技术本栏目责任编辑:冯蕾 网络通讯及安全第7卷第1期(2011年1月)Linux 进程调度分析 钟诚,卢卫恒,李德勇 ( ...
- linux --- 进程调度
2019独角兽企业重金招聘Python工程师标准>>> Linux进程调度笔记 一:Linux进程的四大要素 1:一段供进程执行的程序,该程序可以被多个进程执行. 2:独立的内核堆栈 ...
最新文章
- 斯坦福大学统计系教授带你玩转微生物组分析
- 从Promise来看JavaScript中的Event Loop、Tasks和Microtasks
- reloaddata 跳动_纸跳动像素
- jquery.cookie.js操作cookie实现“记住密码”
- DFS:C 小Y的难题(1)
- 阿里文娱再调整:李捷出任阿里影业总裁,戴玮任文娱COO
- 操作excel方便么_【Excel好推荐】专业仪表板
- mui 批量上传图片 php,MUI+Hbuilder之多图片,单图片上传(五)
- ckEditor使用JS代码调用的方法
- mysql字符串区分大小写的问题
- java正则和python正则差距,在C/Java中处理正则表达式比在Python中快多少?
- IDEA常用快捷键整理大全(非常详细)持续更新中...
- 【信号与系统实验】实验三 连续时间LTI系统的时域分析
- python keyboard backspace_键盘记录器在按backspace键时抛出错误(Python)
- python降低图像分辨率_降低DDS图像的分辨率
- 邮箱发送附件,附件变成了bin文件
- 0xff到底是多少(0x是16进制,f对应11111,因此是11111111,也就是2的8次方-1=255)
- java 解码和加密 汉信码_java中的编码与解码
- 删除office的产品秘钥
- 前端解决手机拍照旋转问题及图片压缩上传
热门文章
- TensorRT IRNNv2Layer
- 半导体群聚、虚拟垂直、整合
- 2021年大数据Spark(三十七):SparkStreaming实战案例二 UpdateStateByKey
- HarmonyOS 字体在自身控件中居中(使用text_alignment)
- JSONObject没有fromObject方法(Json lib 库的使用)
- Manifest merger failed : uses-sdk:minSdkVersion 15 cannot be smaller than version 16 declared in lib
- 基于uFUN开发板的心率计(一)DMA方式获取传感器数据
- 【js操作url参数】获取指定url参数值、取指定url参数并转为json对象
- [bzoj1582][Usaco2009 Hol]Holiday Painting 节日画画_线段树
- Ubuntu 安装 CUDA 和 cuDNN 详细步骤