操作系统如何选择在CPU中运行下一个进程?

时间:2016-07-21 17:10:00

标签: linux operating-system kernel scheduler

我知道在内核中维护了一个进程控制块,问题是:

如果正在CPU中运行Process X,并且发生了上下文切换,那么是否会运行链接到进程X的PCB的进程?或者将在就绪队列中运行随机进程?考虑到所有流程都具有相同的优先级。

提前致谢!

1 个答案:

答案 0 :(得分:2)

如果进程X花费了它的量子,则将调用调度程序。如果存在更高或相同动态优先级的其他进程,则将发生上下文切换。如果没有其他进程,并且当前进程仍准备运行(未阻止),则将在没有上下文切换的情况下恢复。每个优先级都有两个队列activeexpired;所以如果我们有几个具有相同优先级的进程,它们将一个接一个地运行。

检查Linux中的https://criticalblue.com/news/wp-content/uploads/2013/12/linux_scheduler_notes_final.pdf进程调度 - 关键蓝色。 Volker Seeker - 爱丁堡大学05.12.2013(linux 3.1)

  

进程调度程序..具有以下任务:

     
      
  • •在所有当前正在运行的进程中平均共享CPU
  •   
  • •考虑到调度类/策略和流程优先级,选择适当的流程以便在下一步运行
  •   
  • •在SMP系统中的多个核心之间平衡过程

         

    struct task_struct *(* pick_next_task)(struct rq * rq);

  •   
     

5.1调度程序入口点..其主要目标是找到要运行的下一个任务,然后将其分配给本地变量。

  next = pick_next_task(rq);
     ...
  if (likely(prev != next)) {
        rq->nr_switches++;

 /*
 * Pick up the highest-prio task:
 */
static inline struct task_struct *
pick_next_task(struct rq *rq)
{
    const struct sched_class *class;
    struct task_struct *p;
    /*
     * Optimization: we know that if all tasks are in
     * the fair class we can call that function directly:
     */
    if (likely(rq->nr_running == rq->cfs.nr_running)) {
        p = fair_sched_class.pick_next_task(rq);
        if (likely(p))
            return p;
    }
    for_each_class(class) {
        p = class->pick_next_task(rq);
        if (p)
            return p;
    }
    BUG(); /* the idle class will always have a runnable task */
}
     

pick_next_task()也在sched.c中实施。它遍历我们的调度类列表,以查找具有可运行任务的具有最高优先级的类(请参阅上面的调度类)。如果找到该类,则调用调度类钩子。由于大多数任务都由sched_fair class处理,因此在函数开头实现了此类的快捷方式。

     

现在schedule()检查pick_next_task()是否找到了新任务,或者它是否再次选择了之前运行的相同任务。如果是后者,则不执行任务切换,并且当前任务仅继续运行。如果找到新任务(更可能是这种情况),则通过调用context_switch()来执行实际任务切换。在内部,context_switch()切换到新任务的内存映射并交换寄存器状态和堆栈。

还有https://www.cs.columbia.edu/~smb/classes/s06-4118/l13.pdf Linux Scheduler,CS CU,COMS W4118,

  

为每个处理器分别设置一个运行队列。   每个处理器仅从其自己的队列中选择要运行的进程。 ..   队列定期重新平衡

     

基本调度算法:找到具有可运行的最高优先级队列   处理;找到该队列上的第一个进程;计算其量子大小;让它运行;当它的时间到了,把它放在过期的清单上;重复。

     

运行队列:

     
      
  • 140个单独的队列,每个优先级一个
  •   
  • 实际上,这个数字可以在给定的网站上更改
  •   
  • 实际上,有两套,activeexpired
  •   
  • 实时流程的优先级0-99
  •   
  • 正常过程的优先级100-139;通过nice()系统调用设置的值
  •   
     

使用Quanta(13/40):

     
      
  • 每次滴答,减少当前运行过程的量子
  •   
  • 如果时间变为零,则过程完成
  •   
  • 如果流程是非交互式的,请将其放在已过期的列表中
  •   
  • 如果流程是交互式的,请将其放在当前优先级队列的末尾
  •   
  • 如果该优先级没有其他内容,它将立即再次运行
  •   
  • 当然,通过跑这么多,奖金将会下降,优先级和互动状态也会下降
  •   
     

避免无限期超越:

     
      
  • 有两组140个队列,activeexpired
  •   
  • 系统只运行active个队列的进程,并在用完量子时将它们放在expired个队列上
  •   
  • 当活动队列的优先级为空时,调度程序将查找次高优先级队列
  •   
  • 运行所有活动队列后,activeexpired队列将被交换
  •   
  • 有指向当前数组的指针;在循环结束时,指针被切换
  •