码迷,mamicode.com
首页 > 系统相关 > 详细

linux 进程调度2

时间:2020-02-21 20:13:40      阅读:87      评论:0      收藏:0      [点我收藏+]

标签:调度   count   global   struct   设置   抢占式   cal   标识   用户   

抢占式调度

两种情况:

  1. 执行太久, 需切换到另一进程;
  2. 高优先级进程被唤醒

切换到另一进程实现:

  时钟中断处理函数会调用 scheduler_tick()查看是否是需要抢占的时间点

void scheduler_tick(void)
{
  int cpu = smp_processor_id();
  struct rq *rq = cpu_rq(cpu);
  struct task_struct *curr = rq->curr;
......
  curr->sched_class->task_tick(rq, curr, 0);
  cpu_load_update_active(rq);
  calc_global_load_tick(rq);
......
}
  1. 由时钟中断触发检测, 中断处理调用 scheduler_tick
  2. 取当前进程 task_struct->task_tick_fair()->取 sched_entity cfs_rq 调用 entity_tick()
  3. entity_tick() 调用 update_curr 更新当前进程 vruntime, 调用 check_preempt_tick 检测是否需要被抢占
  4. check_preempt_tick 中计算 ideal_runtime(一个调度周期中应该运行的实际时间), 若进程本次调度运行时间 > ideal_runtime, 则应该被抢占
  5. 要被抢占, 则调用 resched_curr, 设置 TIF_NEED_RESCHED, 将其标记为应被抢占进程(因为要等待当前进程运行 `__schedule`)

高优先级进程被唤醒实现:

  1. 当 I/O 完成, 进程被唤醒, 若优先级高于当前进程则触发抢占
  2. try_to_wake_up()->ttwu_queue() 将唤醒任务加入队列 调用 ttwu_do_activate 激活任务
  3. 调用 tt_do_wakeup()->check_preempt_curr() 检查是否应该抢占, 若需抢占则标记

标识当前运行中的进程应该被抢占了,但是真正的抢占动作并没有发生

抢占时机

进程调用 `__schedule`,:分为用户态和内核态
用户态进程
        时机-1: 从系统调用中返回, 返回过程中会调用 exit_to_usermode_loop, 检查 `_TIF_NEED_RESCHED`, 若打了标记, 则调用 schedule(),调用的过程和上一节解析的一样,会选择一个进程让出 CPU,做上下文切换。
        时机-2: 从中断中返回, 中断返回分为返回用户态和内核态(汇编代码: arch/x86/entry/entry_64.S), 返回用户态过程中会调用 exit_to_usermode_loop()->shcedule()
内核态进程
        时机-1: 发生在 preempt_enable() 中, 内核态进程有的操作不能被中断, 会调用 preempt_disable(), 在开启时(调用 preempt_enable) 时是一个抢占时机, 会调用 preempt_count_dec_and_test(), 检测 preempt_count 和标记, 若可抢占则最终调用 `__schedule`
        时机-2: 发生在中断返回, 也会调用 `__schedule`

 

总结

技术图片

 

 

参考:《趣谈Linux操作系统》调度(中)

linux 进程调度2

标签:调度   count   global   struct   设置   抢占式   cal   标识   用户   

原文地址:https://www.cnblogs.com/mysky007/p/12342505.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!