Fork me on GitHub

Linux 内核学习笔记(二)——Process Scheduling


Process Scheduling

顾名思义,Process Scheduler就是一个kernel subsystem 使得多个process可以顺利工作起来。它决定哪个process何时工作,工作多久。从外部看来,这给人一种多个process同时工作的假象。

对于有多个processor的设备来说,可以做到多个process同时工作,对于单个processor来说就是多任务,类似分时复用的模式来达到并发的目的。

CFS

开始的时候Unix系统都是O(1)scheduler,现在更常使用Completely Fair Scheduler ,CFS。

process可以划分成两类:I/O-Bound 、 Processor-Bound Process I/O-Bound:执行所需时间短,但是执行频繁,要求低延迟,更好地人机交互友好性(比如打字输入,不能半天屏幕上还没有显示输入的字母);Processor-Bound:执行所需时间长,不需要频繁运行(类似于执行MATLAB这样的大程序)

scheduler 算法是使用优先级为基础的scheduling。其中有:

  • nice value:优先级的序号值越小,代表约优先,所分配的时间(timeslice)就越多,反之序号越大,执行分配时间越短。

  • real-time priority: 这个是序号值越大越优先,并且最小的real-time priority都比nice value 更优先!!

对于timeslice,太长使得用户交互体验变差,太短系统一直在不同process之间切换,疲于奔命,耗费了很多时间,效率亦不高。CFS很好地解决了这样的问题(尽管也应该有自己缺陷),采用比例的形式(proportion)分配时间,而不是通过给每一个nice value固定timeslice. 而这个比例就是通过nice value的值来辅助确定的。例如,如果一个需要耗费更少时间的process进入kernel,那么当前的process就会被停止,优先执行这个消耗更上比例时间的process。

为了较为理想地在不同process之间切换,设定了target latency。比如设定其为20 milliseconds,2个任务时就是每个任务10,4个process时每个5.但是当任务越来越多,甚至是无穷多时,每个process分摊的时间就是0,这连不同任务之间切换的时间都不够。为此设定了一个timeslice下限:1 milliseconds。

CFS也会记录每个process运行了多久,还需要运行多久。CFS总是找到最小的vruntime,然后执行这个process。它是通过red-black tree去管理执行时间,进而找到这个最小的vruntime的process。

Whatever the case, the kernel behavior is the same:The task marks itself as sleeping,
puts itself on a wait queue, removes itself from the red-black tree of runnable, and calls
schedule() to select a new process to execute.

Sleeping is handled via wait queues.

Preemption

User Preemption

In short, user preemption can occur

  • When returning to user-space from a system call
  • When returning to user-space from an interrupt handler

Preemption:User Preemption和kernel Preemption

以kernel Preemption为例,大致就是两个任务在执行时,如果一个任务通过system call进入到kenel- space执行状态,另一个任务想要通过system call调用。如果不是 Preemption的内核,必须等待这个任务在kernel中完全结束离开之后才能进行,linux支持 Preemption,这样就可以抢占式地暂停当前正在运行的任务,让另一个任务在kernel中优先执行。缺点就是增加了内核的复杂性,处理起来难度大一些,但是对于real time系统来说,体验性较好。

Kernel preemption can occur

  • When an interrupt handler exits, before returning to kernel-space
  • When kernel code becomes preemptible again
  • If a task in the kernel explicitly calls schedule()
  • If a task in the kernel blocks (which results in a call to schedule() )

real-time priority

  • SCHED_FIFO: 简单的first in first out,没有timeslice的优先级模式;
  • SCHED_RR : 和SCHED_FIFO类似,区别在于,当前process的timeslice执行完毕之后,其他程序之间可以通过优先级竞争来争取执行。

System Calls

application programing interface(API)

在Unix world 中最常用的API接口就差POSIX standard。主要还是借助于C library的形式实现的。一般都是通过在C函数库来调用system call。 每一个system call都有一个特定的number,通过这个number来进行调用。

值得注意的是,设定一个新的system call是非常容易的,只需要进行定义、在各个库文件里面进行生命,然后编译(记住和驱动编程的挂载不太一样),烧录进kernel即可。但是这是不建议去做的事情,也是没有必要做的。

参考文献:

  1. Love, Robert . "Linux Kernel Development." (2008).
  2. https://stackoverflow.com/questions/5283501/what-does-it-mean-to-say-linux-kernel-is-preemptive
  3. https://stackoverflow.com/questions/817059/what-is-preemption-what-is-a-preemtible-kernel-what-is-it-good-for

本文作者:LT_Rock

本文链接https://www.cnblogs.com/LT-Rock/p/13542073.html

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!


posted @ 2020-08-21 17:18  LT_Rock  阅读(422)  评论(0)    收藏  举报