当前位置: 首页 > article >正文

抢占式调度是如何发生的

最常见的现象就是一个进程执行时间太长了,是时候切换到另一个进程了。那怎么衡量一个进程的运行时间呢?在计算机里面有一个时钟,会过一段时间触发一次时钟中断,通知操作系统,时间又过去一个时钟周期,这是个很好的方式,可以查看是否是需要抢占的时间点。

check_preempt_tick 先是调用 sched_slice 函数计算出的 ideal_runtime。ideal_runtime 是一个调度周期中,该进程运行的实际时间。

sum_exec_runtime 指进程总共执行的实际时间,prev_sum_exec_runtime 指上次该进程被调度时已经占用的实际时间。每次在调度一个新的进程时都会把它的 se->prev_sum_exec_runtime = se->sum_exec_runtime,所以 sum_exec_runtime-prev_sum_exec_runtime 就是这次调度占用实际时间。如果这个时间大于 ideal_runtime,则应该被抢占了。

除了这个条件之外,还会通过 __pick_first_entity 取出红黑树中最小的进程。如果当前进程的 vruntime 大于红黑树中最小的进程的 vruntime,且差值大于 ideal_runtime,也应该被抢占了。

标记一个进程应该被抢占,都是调用 resched_curr,它会调用 set_tsk_need_resched,标记进程应该被抢占,但是此时此刻,并不真的抢占,而是打上一个标签 TIF_NEED_RESCHED。

当一个进程在等待一个 I/O 的时候,会主动放弃 CPU。但是当 I/O 到来的时候,进程往往会被唤醒。这个时候是一个时机。当被唤醒的进程优先级高于 CPU 上的当前进程,就会触发抢占。try_to_wake_up() 调用 ttwu_queue 将这个唤醒的任务添加到队列当中。ttwu_queue 再调用 ttwu_do_activate 激活这个任务。ttwu_do_activate 调用 ttwu_do_wakeup。这里面调用了 check_preempt_curr 检查是否应该发生抢占。如果应该发生抢占,也不是直接踢走当前进程,而是将当前进程标记为应该被抢占。

对内核态的执行中,被抢占的时机一般发生在 preempt_enable() 中。

在内核态的执行中,有的操作是不能被中断的,所以在进行这些操作之前,总是先调用 preempt_disable() 关闭抢占,当再次打开的时候,就是一次内核态代码被抢占的机会。

就像下面代码中展示的一样,preempt_enable() 会调用 preempt_count_dec_and_test(),判断 preempt_count 和 TIF_NEED_RESCHED 是否可以被抢占。如果可以,就调用 preempt_schedule->preempt_schedule_common->__schedule 进行调度。还是满足进程调度第一定律的。

在内核态也会遇到中断的情况,当中断返回的时候,返回的仍然是内核态。这个时候也是一个执行抢占的时机,现在我们再来上面中断返回的代码中返回内核的那部分代码,调用的是 preempt_schedule_irq。

此文章为10月Day28学习笔记,内容来源于极客时间《趣谈Linux操作系统》,推荐该课程。


http://www.kler.cn/news/107688.html

相关文章:

  • 大厂面试题-JVM为什么使用元空间替换了永久代?
  • Spring Cloud Gateway + Knife4j 4.3 实现微服务网关聚合接口文档
  • golang工程——grpc-gateway 转发http header中自定义字段到grpc上下文元数据
  • 原始流,缓冲流性能比较
  • 淘宝API接口获取商品信息,订单管理,库存管理,数据分析
  • 计算机网络重点概念整理-第七章 网络安全【期末复习|考研复习】
  • 场效应管器件
  • 【C语言数据结构——————排序(1万字)】
  • VSCode 自动格式化
  • elementUI 特定分辨率(如1920*1080)下el-row未超出一行却换行
  • debian 10 安装apache2 zabbix
  • 五、Qt中的常用类
  • 前端学习之Babel转码器
  • C语言 位操作符 >> << | ^
  • IPv6的主要优势有哪些?
  • Python-pptx教程之一从零开始生成PPT文件
  • TSINGSEE青犀睡岗离岗检测算法——确保加油站安全运营
  • 数据安全的重要性:如何解密[thekeyishere@cock.li].Elbie勒索病毒
  • springboot + redis实现签到与统计功能
  • RabbitMQ消息中间件
  • Linux C语言开发-D7D8运算符
  • python excel接口自动化测试框架
  • vue3 源码解析(2)— ref、toRef、toRefs、shallowRef 响应式的实现
  • 【Linux】虚拟机安装Linux、客户端工具,MobaXterm的使用,Linux常用命令
  • redis archive github
  • 数据结构之队列
  • 消息队列中间件面试笔记总结RabbitMQ,Kafka,RocketMQ
  • el-table(vue2中)滚动条被固定列盖住
  • 为什么axios会有params和data两个参数
  • 数字孪生智慧工厂三维可视化系统解决方案,打造新一代智慧工厂