第四章:进程调度

一、多任务

1.非抢占式多任务

进程会一直执行直到自己主动停止运行(这一步骤称为让步)

2.抢占式多任务

Linux/Unix使用的是抢占式的方式;强制的挂起进程的动作就叫做抢占。进程在被抢占之前能够运行的时间是预先设置好的(也就是进程的时间片)

二、与策略相关的概念

1.进程的消耗类型

  1. I/O消耗型进程

    • 进程的大部分时间用来提交I/O请求或者等待I/O请求
    • 多数用户图形界面(GUI)都属于I/O密集型
  2. 处理器耗费型
    • 时间大多数用在执行代码上
    • 例如MATLAB
    • 往往要延长运行时间并降低调度频率

2.进程优先级

  1. 基于优先级的调度:优先极高的进程先运行;相同优先级的进程按照轮转方式进行调度;
  2. 优先级分为两类
    • nice值(从-20——+19):默认值为0;数值越大意味着优先级越低;可以通过 ps-el查看系统进程列表并找到NI标记列对应的优先级
    • 实时优先级(从0——99):越高的实时优先级级数意味着进程优先级越高
    • 二者互不交互
  3. 时间片
    • 时间片表示进程在被抢占之前所能够持续运行的时间;调度策略必须确定一个默认的时间片;
    • Linux的CFS调度器并没有直接划分时间片到进程,而是将处理器的使用比例划分给了进程。也就是说,其抢占时机取决于新的可执行程序消耗了多少处理器使用比,如果消耗的使用比比当前进程小,则新进程立即投入运行抢占当前进程。

三、Linux调度算法

1.调度器类

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

2.Unix中系统调度问题

  1. 将nice值映射到时间片的话,就必须将nice值对应到处理器的绝对时间;这样会导致进程切换无法最优进行;
  2. 如果使用相对nice值,所带来的效果将会极大取决于其nice的初始值;
  3. 如果执行nice值到时间片的映射,时间片极大受制于定时器。

3.公平调度

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

    • 允许每个进程运行一段时间、循环轮转、选择运行最少的进程作为下一个运行进程;
    • nice值作为进程获得的处理器运行比的权重(而不是完全由nice决定时间片);
    • 每个进程都按照其权重在全部的可运行进程中所占的比例对应的“时间片”来运行

【所谓“鱼与熊掌不可得兼”即如此——越小的调度周期就会表现出越好的交互性,也更接近于“同时完成多任务”这一孜孜追求的目标;然而系统必须承受更高的切换代价和更差的系统吞吐量——甚至将绝大多数精力耗费在这种来回倒腾上】

四、Linux调度的实现

1.时间记账

  • 所有的调度器都必须对进程的运行时间做记账;
  • CFS使用调度器实体结构来追踪运行记账

2.虚拟实时

  • vrntime变量【也就是在上面所说的实体结构中】存放虚拟运行时间。虚拟时间以ns为单位,和节拍定时器无关;
  • update_curr()函数实现了记账功能;计算了当前进程的执行时间并将其存放在data_exec中;然后将运行时间传递给了_update_curr(),由后者再根据当前可运行进程总数对运行时间进行计算,最终确定上述的权重值与当前运行进程的vrntime。

3.进程选择

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

【由此我们可以看到,二叉树中存储的全部是可执行进程】

4.进程调度入口

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

5.睡眠和唤醒

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

    • 进程把自己标记成休眠状态,从可执行红黑树中移除;
    • 放入等待队列——由等待某些时间发生的进程组成的链表,内核用wake_queue_head_t来代表等待队列
  2. 唤醒操作由函数wake_up()进行
    • 它会调用函数try_to _wake_up()将进程设置为TASK_RUNNING状态,调用enqueue_task()将进程放入红黑树中
    • 当然,也存在虚假唤醒进程的状态

五、抢占和上下文切换

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

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

2.Linux系统支持内核抢占

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

linux第四次读书笔记的更多相关文章

  1. linux第四章读书笔记

    第四章 进程调度 一.多任务 多任务操作系统就是能同时并发的交互执行多个进程的操作系统.多任务操作系统使多个进程处于堵塞或者睡眠状态,实际不被投入执行,这些任务尽管位于内存,但是并不处于可运行状态.多 ...

  2. 2013337朱荟潼 Linux第四章读书笔记——进程调度

    第4章 进程调度 0. 总结 调度:调度是一个平衡的过程.一方面,它要保证各个运行的进程能够最大限度的使用CP:另一方面,保证各个进程能公平的使用CPU. 调度功能:决定哪个进程运行以及进程运行多长时 ...

  3. 20135320赵瀚青LINUX第四章读书笔记

    概述 什么是进程调度 进程调度:在可运行态进程之间分配有限处理器时间资源的内核子系统. 一.调度策略 4.1进程类型 I/O消耗型进程:大部分时间用来提交I/O请求或是等待I/O请求,经常处于可运行状 ...

  4. Linux内核分析第四章 读书笔记

    Linux内核分析第四章 读书笔记 第一部分--进程调度 进程调度:操作系统规定下的进程选取模式 面临问题:多任务选择问题 多任务操作系统就是能同时并发地交互执行多个进程的操作系统,在单处理器机器上这 ...

  5. 《Linux内核设计与分析》第四章读书笔记

    <内核设计与实现>第四章读书笔记 第四章:进程调度 进程(操作系统)程序的运行态表现形式. 进程调度程序,它是确保进程能有效工作的一个内核子系统. 调度程序负责决定将哪个进程投入运行,何时 ...

  6. 《Linux内核分析》读书笔记(四章)

    <Linux内核分析>读书笔记(四章) 标签(空格分隔): 20135328陈都 第四章 进程调度 调度程序负责决定将哪个进程投入运行,何时运行以及运行多长时间,进程调度程序可看做在可运行 ...

  7. 《The Linux Command Line》 读书笔记02 关于命令的命令

    <The Linux Command Line> 读书笔记02 关于命令的命令 命令的四种类型 type type—Indicate how a command name is inter ...

  8. 《The Linux Command Line》 读书笔记01 基本命令介绍

    <The Linux Command Line> 读书笔记01 基本命令介绍 1. What is the Shell? The Shell is a program that takes ...

  9. Linux Shell Scripting Cookbook 读书笔记 1

    本系列文章为<Linux Shell Scripting Cookbook>的读书笔记,只记录了我觉得工作中有用,而我还不是很熟练的命令 书是很好的书,有许多命令由于我比较熟悉,可能就没有 ...

随机推荐

  1. VMWare:vSphere6 企业版参考序列号

    HV4WC-01087-1ZJ48-031XP-9A843 NF0F3-402E3-MZR80-083QP-3CKM2 4F6FX-2W197-8ZKZ9-Y31ZM-1C3LZ JZ2E9-6D2D ...

  2. 3.6Python数据处理篇之Numpy系列(六)---Numpy随机函数

    目录 目录 前言 (一)基础的随机函数 (二)轴的随机函数 (三)概率的随机函数 目录 前言 前一段日子学了numpy,觉得无趣,没有学完,不过后来看了看matplotlib,sympy等库时,频频用 ...

  3. cpu的组成及分工

    控制单元是上帝:掌控一切: 运算单元只负责算术和逻辑运算,运算的指令由控制单元提供,数据由寄存器提供: 存储单元:一方面给运算单元提供输入输出,另一方面在控制单元的控制下和内存通信: 控制单元使用运算 ...

  4. Java 浅拷贝,深拷贝

         从Java 强引用.软引用,弱引用http://blog.csdn.net/jltxgcy/article/details/35558465一文中,我们看到把一个对象赋值给另一个对象,本质上 ...

  5. Linux安装solr

    solr官网下载地址为:http://mirror.bit.edu.cn/apache/lucene/solr/ 以7.6.0版本作为实践 1.下载 wget http://mirror.bit.ed ...

  6. P1044-栈-洛谷luogu

    题目背景 栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表. 栈有两种最重要的操作,即poppop(从栈顶弹出一个元素)和pushpush(将一个元素进栈). 栈的重要性 ...

  7. [转]QT4.8.5+qt-vs-addin-1.1.11+VS2010安装配置和QT工程的新建和加载

    1.下载windows下的QT库 QT4.8.5 for vs2010: http://download.qt-project.org/official_releases/qt/4.8/4.8.5/q ...

  8. 动态分析Android程序

    快速定位程序关键点 代码注入法 插入log函数,输出调试信息. const-string v0,"TAG" const-string v1,"info" inv ...

  9. saltstack学习之一:服务架构以及相关配置安装运行

    概要 saltstack是基于Python开发的C/S架构的一款批量管理工具,底层采用动态的连接总线(ZeroMQ消息队列pub/sub方式通信),使用ssl证书签发的方式进行认证管理,使其可以用于编 ...

  10. SkylineGlobe6.5遍历信息树节点方法

    //------------------- //searchGeometries function searchGeometries2(parentNode, callbackFunc) { SGWo ...