chapter 4 进程调度

4.1 多任务

  • 多任务操作系统就是能同时并发的交互执行多个进程的操作系统。
  • 多任务系统可以划分为两类:

     - 非抢占式多任务:
    - 进程会一直执行直到自己主动停止运行(这一步骤称为让步)
    - 抢占式多任务:
    - Linux/Unix使用的是抢占式的方式;强制的挂起进程的动作就叫做抢占。进程在被抢占之前能够运行的时间是预先设置好的(也就是进程的时间片)

4.2 linux的进程调度

  1. O(1)调度器:对大服务器的工作负载很理想,但是缺少交互进程。
  2. 反转楼梯最后期限调度算法(RSDL)
  3. 完全公平调度算法(CFS)

4.3 策略

  • 策略决定调度程序在合适让什么程序运行。

4.3.1 进程分类

  • I/O消耗型

    • 进程的大部分时间用来提交I/O请求或者等待I/O请求,经常处于可运行状态但是运行时间很短,等待更多的请求时最后总会阻塞。
  • 处理器消耗型

    • 把时间大多用在执行代码上,除非被抢占,否则通常都会不停运行。
  • 调度策略通常要在两个矛盾的目标中间寻找平衡:

    • 进程调度迅速(响应时间短)
    • 最大系统利用率(高吞吐量)
  • Linux倾向于优先调度I/O消耗型进程

4.3.2 进程优先级

  • 调度算法中最基本的一类就是基于优先级的调度:

    • 优先极高的进程先运行;相同优先级的进程按照轮转方式进行调度
  • 调度程序总是选择时间片未用尽而且优先级最高的进程运行。
  • Linux采用了两种不同的优先级范围:
    • nice值(从-20——+19):默认值为0;数值越大意味着优先级越低;可以通过 ps-el查看系统进程列表并找到NI标记列对应的优先级
    • 实时优先级(从0——99):越高的实时优先级级数意味着进程优先级越高
    • 二者互不交互

4.3.3 时间片

  • 时间片表示进程在被抢占前所能持续运行的时间。
  • 调度策略必须确定一个默认的时间片;
  • Linux的CFS调度器并没有直接划分时间片到进程,而是将处理器的使用比例划分给了进程。也就是说,其抢占时机取决于新的可执行程序消耗了多少处理器使用比,如果消耗的使用比比当前进程小,则新进程立即投入运行抢占当前进程。

4.3.4 调度策略的活动

4.4 linux调度算法

4.4.1 调度器类

  1. Linux调度器是以模块方式提供的(也就是调度器类),目的是允许不同类型的进程可以有针对性地选择调度算法
  2. 调度器类允许多种不同的可动态添加的调度算法并存,调度属于自己范畴的进程;
  3. 调度器代码会按照优先级顺序遍历调度类,拥有一个可执行进程的最高优先级的调度器类胜出,去选择下面要执行的那一个程序;

4.4.2 Unix系统中的进程调度

Unix使用的调度算法是分配绝对的时间片,这样就会引发固定的切换频率,不利于公平性。 而Linux采用的CFS完全摒弃了时间片,分配给进程一个处理器使用比重,保证恒定的公平性和变动的切换频率。

4.4.3 公平调度(CFS)

  • CFS的出发点基于一个简单的理念:进程调度的效果应当如同系统具备一个理想中的完美任务处理器。
  • CFS的做法如下:

    • 允许每个进程运行一段时间、循环轮转、选择运行最少的进程作为下一个运行进程;
    • nice值作为进程获得的处理器运行比的权重 即:绝对的nice值不再影响调度决策,它们的相对值才会影响处理器时间的分配比例——几何加权。
    • 每个进程都按照其权重在全部的可运行进程中所占的比例对应的“时间片”来运行
  • 目标延迟:无限小调度周期的近似值

  • 最小粒度:每个进程获得的时间片底线,默认为1ms。
  • 没有时间片概念但是仍需维持时间记账。

4.5 linux调度的实现

——即CFS调度算法的实现。

四个组成部分:

- 时间记账
- 进程选择
- 调度器入口
- 睡眠和唤醒

4.5.1 时间记账

  • 所有的调度器都必须对进程的运行时间做记账;
  • CFS使用调度器实体结构来追踪运行记账
  • 1.调度器实体结构
    • CFS使用调度器实体结构来追踪进程运行记账:
  • 2.虚拟实时
    • CFS使用了vruntime变量来存放进程的虚拟运行时间,用来表示进程到底运行了多少时间,以及它还应该运行多久。
    • 这个虚拟运行时间是加权的,与定时器节拍无关。
    • 虚拟运行时间以ns为单位。 
    • 相关的函数是updatecurr(),它计算了当前进程的执行时间并存放入变量deltaexec中,然后又将运行时间传递给_updatecurr();
    • _updatecurr()根据当前可运行进程总数对进行时间进行加权计算,最终将权重值与当前运行进程的vruntime值相加。 

4.5.2 进程选择

  • CFS算法核心:选择具有最小vrntime的任务
  • 具体做法:利用红黑树rbtree(以节点形式存储数据的二叉树)
  • 举例:
    • 选择下一个任务:从根节点中序遍历二叉树,一直到叶子节点(也就是vrntime最小的进程);
    • 向树中加入进程:在进程变为可执行状态或者通过fork()调用第一次创建进程;
    • 从树中删除进程:发生在进程阻塞或者终止的时候

**Linux中,红黑树被称为rbtree,是一个自平衡二叉搜索树,是一种以树节点形式存储的数据,这些数据会对应一个键值,可以通过这些键值来快速检索节点上的数据,而且检索速度与整个树的节点规模成指数比关系。 **

  1. 挑选下一个任务:

    节点键值是可运行进程的虚拟运行时间,进程选择算法是【运行rbtree树种最左边叶子节点所代表的那个进程】,函数是picknextentity() 

  2. 向树中加入进程:
    • 发生在进程被唤醒或者通过fork调用第一次创建进程时。
    • 函数enqueueentity():更新运行时间和其他一些统计数据,然后调用enqueueentity()。 函数enqueue_entity():进行繁重的插入工作,把数据项真正插入到红黑树中: 
  3. 从树中删除进程

    • 删除动作发生在进程堵塞或终止时。

    • 相关函数是dequeueentity()和dequeueentity(): 

4.5.3 调度器入口

  1. 进程调度的主要入口点是函数schedule(),定义在kernel/sched.c中;这正是内和其他部分用于调度进程调度器的入口
  2. 这一函数最重要的工作就是调用picknextstate(),依次检查每一个调度类,并从最高优先级的调度类中,选择最高优先级进程

4.5.4 睡眠和唤醒

  • 进程休眠一定是为了等待一些事件

    • 进程把自己标记成休眠状态,从可执行红黑树中移除;
    • 放入等待队列——由等待某些时间发生的进程组成的链表,内核用wakequeuehead_t来代表等待队列

3. 唤醒操作由函数wake_up()进行

- 它会调用函数try_to _wake_up()将进程设置为TASK_RUNNING状态,调用enqueue_task()将进程放入红黑树中
- 当然,也存在虚假唤醒进程的状态

4.6 抢占和上下文切换

  • 上下文切换由定义在kernel/sched.c中的context_switch()函数负责,每当一个新的进程被选出来准备运行的时候,schedule()就会调用该函数:

    • 调用switch_mm(),负责把虚拟内存从上一个进程映射切换到新的进程中;
    • 调用switch_to(),负责从上一个进程的处理器状态切换到新进程的处理器状态
  • Linux系统支持内核抢占

    • 只要没有锁,内核就可以进程抢占;
    • 为了支持抢占,每个进程的threadinfo都加入了preemptcount计数器(初值为0,每当使用锁的时候就加1,释放锁的时候数值减1),当数值为0的时候,内核就可以抢占
  • 内核抢占发生在:
    • 中断处理程序正在执行且返回内核空间之前;
    • 内核代码再一次具有可抢占性的时候;
    • 内核中的任务显式地调用schedule函数

参考资料

linux内核设计与实现

20135239 益西拉姆 linux内核分析 读书笔记之第四章的更多相关文章

  1. 20135239益西拉姆 Linux内核分析 汇编一个简单的c程序并分析其指令过程

    益西拉姆+<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 第一周linux内核分析 学习笔记 一.计算机 ...

  2. 20135239 益西拉姆 linux内核分析 可执行程序的装载

    益西拉姆 + 原创作品请勿转载 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” week 7 可 ...

  3. 20135239益西拉姆 Linux内核分析 进程的描述和进程的创建

    [益西拉姆 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] 第六周 进程的描述 ...

  4. 20135239益西拉姆 Linux内核分析 操作系统是怎样工作的?

    益西拉姆+ 原创作品+ <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” 堆栈 堆栈是C语言程序运行时 ...

  5. 20135239 益西拉姆 linux内核分析 进程的切换和系统的一般执行过程

    week 8 进程的切换和系统的一般执行过程 [ 20135239 原文请转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course ...

  6. 20135239 益西拉姆 linux内核分析 跟踪分析Linux内核的启动过程

    回顾 1.中断上下文的切换——保存现场&恢复现场 本节主要课程内容 Linux内核源代码简介 1.打开内核源代码页面 arch/目录:支持不同CPU的源代码:其中的X86是重点 init/目录 ...

  7. Linux内核分析 读书笔记 (第四章)

    第四章 进程调度 调度程序负责决定将哪个进程投入运行,何时运行以及运行多长时间.进程调度程序可看做在可运行态进程之间分配有限的处理器时间资源的内核子系统.只有通过调度程序的合理调度,系统资源才能最大限 ...

  8. 20135239 益西拉姆 linux内核分析 扒开系统调用的三层皮(下)

    一. 给MenuOS增加time-asm命令 代码解释 1.-rf:强制删除 2.clone :重新克隆 3.time-asm:显示系统时间的汇编形式 给MenuOS增加time和time-asm命令 ...

  9. 20135239 益西拉姆 linux内核分析 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

    https://drive.wps.cn/preview#l/759e32d65654419cb765da932cdf5cdc 本次直接在wps上写的,因为不能连同图片一起粘贴过来,一个一个粘比较费时 ...

随机推荐

  1. 百度地图在移动端下click无效的解决方案

    这是由于百度地图在移动端屏蔽了click事件,在网上找到一种方法,利用touchClick方法来模拟click事件,代码如下(需要JQ插件): //给jquery添加touchClick方法 (fun ...

  2. 文件的上传和下载--SpringMVC

    文件的上传和下载是项目开发中最常用的功能,例如图片的上传和下载.邮件附件的上传和下载等. 接下来,将对Spring MVC环境中文件的上传和下载进行详细的讲解. 一.文件上传 多数文件上传都是通过表单 ...

  3. hive的优化

    hive.optimize.cp=true:列裁剪hive.optimize.prunner:分区裁剪hive.limit.optimize.enable=true:优化LIMIT n语句hive.l ...

  4. Streamr助你掌控自己的数据(2)——三种整合数据至Streamr的典型场景

    博客说明 所有刊发内容均可转载但是需要注明出处. 三种整合数据至Streamr的典型场景 本系列文档主要介绍怎么通过Streamr管理自己的DATA,整个系列包括三篇教程文档,分别是:教你5分钟上传数 ...

  5. HDFS handler

    http://docs.oracle.com/goldengate/bd1221/gg-bd/GADBD/GUID-85A82B2E-CD51-463A-8674-3D686C3C0EC0.htm#G ...

  6. 使用socket发送http请求(get/post)

    手动发送http请求 解释说明 https://blog.csdn.net/zhangliang_571/article/details/23508953 http://www.cnblogs.com ...

  7. PHP 抽象类和接口区别

    php中抽象类和接口的区别 1) 概念 面向对象的三大概念:封装,继承,多态 把属性和方法封装起来就是类.      一个类的属性和方法被另外的类复制就是继承,PHP里面的任何类都可以被继承,被继承的 ...

  8. Daily Scrum (2015/11/2)

    今日我们完成了博客作业的发布,并且也完成了服务器的配置. 成员 今日工作 时间 明日工作 符美潇 两篇文档的修善和数据库的搭建. 2h 完成数据库搭建,并能爬取数据提供给第二小组使用 潘礼鹏 编写两篇 ...

  9. 20135313-exp1

    北京电子科技学院(BESTI) 实     验    报     告 课程:Java程序设计 班级:1353 姓名:吴子怡 学号:20135313 成绩:            指导教师:娄嘉鹏  实 ...

  10. Chapter 10 软件测试

    软件测试是软件质量保证的一项关键活动,验证与确认是贯穿软件生命周期的规范化评估方法.软件验证则试图证明在软件生存的各个阶段是否满足客户的需求,软件确认是一系列的活动和过程,两个活动相互独立但却相辅相成 ...