为了弄清楚在多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 实时调度(源码分析)相关推荐

  1. 【Linux 内核】实时调度类 ① ( 进程分类 | 实时进程、普通进程 | Linux 内核 SCHED_FIFO、SCHED_RR 调度策略 | 实时调度实体 sched_rt_entity )

    文章目录 一.进程分类 ( 实时进程 | 普通进程 ) 二.Linux 内核调度策略 1.SCHED_FIFO 调度策略 2.SCHED_RR 调度策略 三.实时调度实体 sched_rt_entit ...

  2. arm linux 进程调度,详解ARM Linux 2.4.x进程调度

    Linux2.4.x是一个基于非抢占式的多任务的分时操作系统,虽然在用户进程的调度上采用抢占式策略,但是而在内核还是采用了轮转的方法,如果有个内核态的线程恶性占有CPU不释放,那系统无法从中解脱出来, ...

  3. linux 进程调度ppt,第章 Linux进程调度.ppt

    第章 Linux进程调度 * * SCHED_FIFO 与 SCHED_RR 的区别是: 当进程的调度策略为前者时,当前实时进程将一直占用 CPU 直至自动退出,除非有更紧迫的. 优先级更高的实时进程 ...

  4. linux进程调度采取的是,Linux进程调度

    进程状态 进程调度就是让进程从一种状态切换到另一种状态.Linux中进程的主要状态如下, 值 状态 缩写 含义 0 TASK_RUNNING R 正在运行或可运行 1 TASK_INTERRUPTIB ...

  5. 【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 字段 ...

  6. Linux进程调度 - 实时调度器 LoyenWang

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  7. Linux进程管理 (9)实时调度类分析,以及FIFO和RR对比实验

    关键词:rt_sched_class.SCHED_FIFO.SCHED_RR.sched_setscheduler().sched_setaffinity().RR_TIMESLICE. 本文主要关注 ...

  8. Linux进程调度器概述--Linux进程的管理与调度(十五)

    日期 内核版本 架构 作者 GitHub CSDN 2016-06-14 Linux-4.6 X86 & arm gatieme LinuxDeviceDrivers Linux进程管理与调度 ...

  9. linux操作的进程调度没有采用,Linux进程调度分析

    Computer Knowledge and Technology 电脑知识 与技术本栏目责任编辑:冯蕾 网络通讯及安全第7卷第1期(2011年1月)Linux 进程调度分析 钟诚,卢卫恒,李德勇 ( ...

  10. linux --- 进程调度

    2019独角兽企业重金招聘Python工程师标准>>> Linux进程调度笔记 一:Linux进程的四大要素 1:一段供进程执行的程序,该程序可以被多个进程执行. 2:独立的内核堆栈 ...

最新文章

  1. 斯坦福大学统计系教授带你玩转微生物组分析
  2. 从Promise来看JavaScript中的Event Loop、Tasks和Microtasks
  3. reloaddata 跳动_纸跳动像素
  4. jquery.cookie.js操作cookie实现“记住密码”
  5. DFS:C 小Y的难题(1)
  6. 阿里文娱再调整:李捷出任阿里影业总裁,戴玮任文娱COO
  7. 操作excel方便么_【Excel好推荐】专业仪表板
  8. mui 批量上传图片 php,MUI+Hbuilder之多图片,单图片上传(五)
  9. ckEditor使用JS代码调用的方法
  10. mysql字符串区分大小写的问题
  11. java正则和python正则差距,在C/Java中处理正则表达式比在Python中快多少?
  12. IDEA常用快捷键整理大全(非常详细)持续更新中...
  13. 【信号与系统实验】实验三 连续时间LTI系统的时域分析
  14. python keyboard backspace_键盘记录器在按backspace键时抛出错误(Python)
  15. python降低图像分辨率_降低DDS图像的分辨率
  16. 邮箱发送附件,附件变成了bin文件
  17. 0xff到底是多少(0x是16进制,f对应11111,因此是11111111,也就是2的8次方-1=255)
  18. java 解码和加密 汉信码_java中的编码与解码
  19. 删除office的产品秘钥
  20. 前端解决手机拍照旋转问题及图片压缩上传

热门文章

  1. TensorRT IRNNv2Layer
  2. 半导体群聚、虚拟垂直、整合
  3. 2021年大数据Spark(三十七):SparkStreaming实战案例二 UpdateStateByKey
  4. HarmonyOS 字体在自身控件中居中(使用text_alignment)
  5. JSONObject没有fromObject方法(Json lib 库的使用)
  6. Manifest merger failed : uses-sdk:minSdkVersion 15 cannot be smaller than version 16 declared in lib
  7. 基于uFUN开发板的心率计(一)DMA方式获取传感器数据
  8. 【js操作url参数】获取指定url参数值、取指定url参数并转为json对象
  9. [bzoj1582][Usaco2009 Hol]Holiday Painting 节日画画_线段树
  10. Ubuntu 安装 CUDA 和 cuDNN 详细步骤