进程的调度程序是保证进程能有效工作的一个内核子系统。调度程序负责决定将哪个进程投入运行,何时运行以及运行多少时间。简单的来说,调度程序就是在给一堆就绪的进程分配处理器的时间,调度程序是多任务操作系统的基础。调度程序的原则就是最大限度的使用cpu的资源,也就是说,当系统中只要有可运行的进程,就不能让cpu处于空闲的状态,如果系统中没有就绪的进程时,则cpu会运行一个idle进程。

1.多任务

多任务操作系统就是能够同时并发的交互执行多个进程的操作系统,需要注意这里是并发,而不是并行。如果你的计算机有两个或者两个以上的cpu那么,你的计算机就可以真正同时、并行的执行多个任务。多任务操作系统可以分为两类:抢占式多任务和非抢占式多任务。

抢占式多任务中,由调度程序来决定什么时候停止一个进程的执行,这种由调度程序强行停止一个进程执行的动作称为抢占(preemption)。进程在被抢占之前运行的时间是固定的,而且有一个专门的名字,叫做时间片(timeslice)。时间片实际上是分配给每个进程的处理器时间段。

而非抢占式多任务是由进程自己做出让步,在执行了一段时间之后,主动地让出cpu。进程主动挂起自己的操作称为让步(yielding),如果某个进程悬挂起来并且拒不作出让步的话,可能会导致操作系统崩溃。

所以总述上面的两种情况,抢占式多任务就像“法律”,只要时间到了,就把你撤下来。而非抢占式却像“道德”一样,你要是有道德,执行了一会之后,你就自己撤下来,如果有的“人”占着茅坑不拉屎,那其他进程除了用“道德”谴责它,也没有其他的办法了。

2.linux进程调度

linux最初的进程调度程序是非常原始的,很难适应一些众多的可运行进程和多处理器环境。后来从linux2.5开始,对linux的进程调度程序做了大的调整,使用了称为O(1)的调度算法,这个算法引起算法行为而得名。O(1)调度算法虽然在数以十计的多处理器上能表现出近乎完美的特性和可扩展性,但是由于这个算法在调度交互进程的时候并没有表现出很理想的效果。所以在linux2.6的开发初期,提出了CFS算法,即完全公平调度算法。

3.策略

(1)IO消耗型进程和处理器消耗型进程

IO消耗型进程指的是进程的大部分时间是用来等待IO的操作,例如图形用户界面(GUI)程序就属于IO消耗型程序,这个程序需要不断的监听来自用户的输入。这样的进程经常处于可运行的状态,但是每次运行的时间都很短。

处理器消耗型进程是指进程的大部分时间用在执行代码上,比如大型的计算程序MATLAB就属于处理器消耗型进程。

还有一些应用程序虽然划分为IO消耗型进程,但是也有处理器消耗型进程的特征。例如,字处理程序,在大多数时间可能等待来自用户的输入,但是在某段时间该程序又可能粘住处理器疯狂的进行语法和拼写错误的检查。

调度程序需要在两个矛盾目标中寻找平衡————进程的迅速响应和高吞吐量。unix和linux为了获得良好的用户响应,因此都倾向于调度IO消耗型进程。

(2)进程优先级

调度算法中最基本的一种就是基于进程优先级的调度,这是一种根据进程的价值和其对处理器的时间需求来对进程分级的一种想法。通常的做法是优先级高的进程先执行,低的后运行,相同优先级的进程按轮转方式进行调度(一个接一个,重复进行)。在某些操作系统中,优先级高的进程的使用的时间片也长一些。调度程序总是选择优先级高的,并且时间片尚未用尽的进程。

linux系统采用了两种不同类别的优先级,第一种是使用nice值,范围是从-20到+19,值越大表示优先级越低。这个优先级适用于一般的进程。

另外,linux对实时进程采用实时优先级,值从0-99,值越大代表优先级越高。实时进程的优先级都高于普通进程,因此这两个进程优先级是处于两个互不相交的范围内。

(3)时间片

时间片是一个数值,他表示进程在被抢占前能够持续运行的时间。时间片过长会导致系统对交互的响应表现欠佳,时间片过短,却又明显增大进程切换带来的处理器时间消耗。所以IO消耗型进程和处理器消耗型进程的矛盾在这里又再次显现出来,IO消耗型进程不需要长的时间片,而处理器消耗型进程则希望时间片越长越好。

长时间片将导致系统的交互性表现欠佳,很多的操作系统都很重视这一点,因此将时间片设置的很短,如10ms。但是linux的CFS调度算法并没有直接分配时间片到进程,它是将处理器的使用比分给了进程,这样进程获得的处理器的时间是和系统负载密切相关的。这个比例还会受到nice值的影响,nice值作为权重将调整进程使用处理器时间的使用比。具有更高nice值(低优先级)的进程将被赋予低权重,从而丧失一小部分处理器的使用比,而具有低nice值(高优先级)的进程江北赋予高权重,从而获得更多的处理器使用比。

在多数的抢占式操作系统中,一个新就绪的进程能否立即执行(即抢占原来的进程),完全取决于新进程的优先级和是否有时间片。而在linux中采用的CFS调度器,其抢占时机取决于新的进程消耗了多少处理器的使用比,如果新就绪的进程消耗的处理器使用比低于当前的进程,则新进程抢占当前进程,立即投入运行。

(4)调度策略的活动

假设现在系统中共有两个进程,一个是文本编辑器,一个是视频编码器,且这两个进程的优先级相同,即nice的值相同。显然,文本编辑器是IO消耗型进程,而视频编码器则是处理器消耗型进程。linux的CFS算法对这两个程序的调度过程驶入下这个样子的:因为文本编辑器的大部分时间都是在等待IO的操作,它每次只执行很短的一段时间,就进入睡眠状态。将处理器让给视频编码器来运行,所以视频编码器的处理器使用比一定是大于文本编辑器的。所以对于文本编辑器来说,当文本的输入到来时,CFS调度器发现文本编辑器的处理器使用比小于视频编码器的处理器使用比,所以果断抢占视频编码器,把处理器让给文本编辑器。

4.linux调度算法

(1)调度器类

linux的调度器是以模块方式提供的,这样做的目的是为了不同类型的进程可以有针对性的选择调度算法。这种模块化结构称为调度器类,它允许多种不同的可动态添加的调度算法并存,调度属于自己范围的进程。每一个调度器都有一个优先级,基本的调度器代码定义在<kernel/sched.c>文件中,这个代码会按照优先级顺序遍历调度器类,有最高优先级的调度器类胜出,由它区选择哪一个程序来执行。

CFS是针对普通进程的调度类,在linux中称为SCHED_NORMAL,CFS的算法定义在<kernel/sched_fair.c>文件中。

(2)unix系统中的进程调度

现在的进程调度器有两个基本的概念:时间片和优先级。进程一旦启动就会有一个默认的时间片,具有高优先级的进程会执行的更加频繁,而且在多数系统上也会分配更多的时间片。在unix系统中,进程优先级以nice值输出给用户空间,在现实中有很多的问题:

第一个问题,将nice值映射到时间片,就需要将nice的单位值对应到处理器的绝对时间,这将会导致进程切换无法最优进行。

第二个问题,涉及相对nice值,同时和前一个问题也脱不了干系。

第三个问题,如果执行nice值到时间片的映射,我们需要能分配一个绝对时间片,而且这个绝对时间片必需在内核的测试范围内。

第四个问题,关于基于优先级调度器为了优化交互任务而唤醒相关进程的问题。

(3)公平调度(CFS)

CFS的出发点基于一个简单的理念:进程调度的效果如同系统具备一个理想中的完美多任务处理器。在这种系统中,每个进程将获得1/n的处理器时间,n是可运行进程的数目。同时,可以调度给他们无限小的处理器周期,所以在任何可测量周期内,我们给予n个进程中每个进程同样多的运行时间。举例来说,如果我们运行两个进程,在标准unix调度模型中,我们先运行其中一个5ms,然后再运行另一个进程5ms,但他们任何一个在运行时都将100%占有处理器。而理想的模型是,在这10ms中,这两个进程同时执行,每个进程使用处理器的一半的能力。

但是理想的模型一般是不能实现的,并且如果将cpu的使用比划分的很小的话,也会造成系统性能的额外消耗,不断的将进程换入换出将会导致系统性能的严重下降。因此CFS算法都考虑到了这些因素。CFS的做法是允许每个进程运行一段时间、循环轮转、选择运行量最小的进程作为下一个执行的进程。而不再采用时间片,CFS在所有可运行进程的基础上计算出一个进程应该运行多久,而不是依靠nice值来计算时间片。

进程调度(一)--linux内核设计与实现读书笔记相关推荐

  1. Linux内核设计与实现 读书笔记

    第二章 Linux内核 1 内核开发特点 1)内核编译时不能访问C库: 2)浮点数很难使用: 3)内核只有一个定长堆栈: 4)注意同步和并发. 第三章 进程管理 1 current宏:查找当前运行进程 ...

  2. linux内核设计与实现看不懂,Linux内核设计与实现读书笔记

    Unix强大的根本原因: Unix简洁, 提供几百个系统调用, 设计目的明确 Unix中 所有东西都被当做文件对待 Unix内核和相关系统工具是用C语言开发的, 移植能力强大 Unix进程创建迅速, ...

  3. Linux内核设计与实现读书笔记

    1.进程管理 内核通过task_struct管理进程. 2.进程调度 1.可执行队列runqueue. 2.用户抢占.从中断返回或者系统调用返回的时候发生. 3.系统调用 1.系统调用参数放在寄存器里 ...

  4. linux+模块与设备关系,linux内核设计与实现读书笔记——设备和模块

    一.设备类型 1.块设备 blkdev:以块为单位寻址,支持重定位(数据随机访问),通过块设备节点来访问. 2.字符设备cdev:不可寻址,提供数据流访问,通过字符设备节点访问. 3.网络设备:对网络 ...

  5. Linux内核设计与实现学习笔记目录

    **注:**这是别人的笔记,我只是把目录抄过来 <Linux内核设计与实现学习笔记> 1.<Linux内核设计与实现>读书笔记(一)-内核简介 2.<Linux内核设计与 ...

  6. 初探内核之《Linux内核设计与实现》笔记上

    内核简介  本篇简单介绍内核相关的基本概念. 主要内容: 单内核和微内核 内核版本号 1. 单内核和微内核   原理 优势 劣势 单内核 整个内核都在一个大内核地址空间上运行. 1. 简单. 2. 高 ...

  7. linux内核双向循环队列,读书笔记之linux内核设计与实现(2)进程调度

    调度程序是内核的组成部分,它负责选择下一个要运行的进程.进程调度程序可看作在可运行态进程之间分配有限的处理器时间资源的内核子系统. 多任务操作系统就是能够同时并发的交互执行多个进程的操作系统.多任务系 ...

  8. Linux内核设计与实现 总结笔记(第五章)系统调用

    系统调用 内核提供了用户进程和内核交互的接口,使得应用程序可以受限制的访问硬件设备. 提供这些接口主要是为了保证系统稳定可靠,避免应用程序恣意妄行. 一.内核通信 系统调用在用户空间进程和硬件设备之间 ...

  9. 《Linux/Unix设计思想》读书笔记与感想

    英文名:Linux and the Unix Philosophy 作者:Mike Gancarz    翻译:漆渀(ben) NIH - Not Invented Here 准则1:小既是美     ...

最新文章

  1. C语言解析pcap文件得到HTTP信息实例(原创,附源码)
  2. 还在用if(obj!=null)做非空判断?带你快速上手Optional实战性理解!
  3. 算法学习:强连通分量 --tarjan
  4. 银行系统开发必读的三本书!银行IT开发
  5. gdo图形引擎中的旋转角
  6. things to do in English debate: scenario
  7. MySQL min()函数
  8. matlab 显示歌词,【Matlab编程】生日快乐歌(显示歌词)—matlab版
  9. lambda表达式python_你为什么要用lambda表达式?理解它你就知道了
  10. WordPress更改“固定链接”后 ,页面出现404的解决方法
  11. 悟道web标准:前端性能优化
  12. IDEA中JDBC连接MYSQL数据库步骤超详细总结
  13. 激光打印机无线服务器,插上无线翅膀 兄弟1218W激光打印机评测
  14. BZOJ 1984: 月下“毛景树” [树链剖分 边权]
  15. 与面试官的一次促膝长谈:人家也是第一次当面试官,你们答不上来我也特别尴尬!
  16. 实现从淘宝(天猫)定时抓取订单数据、打印电子面单并保存到ERP表中
  17. Mac必备神器之Go2Shell
  18. matplotlib 设置标注方向_原来Matplotlib绘图也可以这么漂亮,这次真的是学习到了...
  19. 2021-03-14我的博客
  20. 性能优化---vue路由懒加载和异步组件

热门文章

  1. DataGrid与SQL Server 2000数据绑定
  2. [转载] python中union函数_如何掌握Python union()方法及怎么用?
  3. [转载] python difference用法_set.difference() 的用法(python3)_举例说明python3 set方法功能
  4. mysql cmmand not found
  5. Duplicate entry 'xxx' for key 'xxx'
  6. python进程问题
  7. R 学习笔记《五》 R语言初学者指南--第二章总结
  8. Html 小插件4 百度搜索代码
  9. 2.C#面向对象基础属性
  10. Android真机没有sqlite3数据库的解决办法