第四章读书笔记——进程调度
第四章 进程调度
多任务
多任务操作系统就是能同时并发的交互执行多个进程的操作系统
多任务操作系统分为:
- 非抢占式多任务(强制的挂起动作就叫做抢占)
- 抢占式多任务(进程主动挂起自己的操作称为让步)
策略
进程可以被分为:
- I/O消耗性(大部分时间用来提交I/O请求或等待I/O请求)
- 处理机消耗型(把大多数时间用在代码上,没有太多的I/O请求)
进程可以同时展示这两种行为,而调度策略通常要在进程相应迅速和最大系统利用率中寻找平衡
Linux采用了两种不同的优先级范围:
- nice值(默认为0,nice值越大优先级越低)
- 实时优先级(可配置,默认情况下0到99,实时优先级值越高进程优先级越高)
时间片:被抢占之前持续运行的时间
Linux调度算法
Linux调度器是以模块方式提供的,其目的是为了允许不同类型的进程可以有针对性的选择算法
现代进程调度器有两个通用的概念:进程优先级和时间片
完全公平调度(CFS)的出发点基于一个简单的理论:进程调度的效果应如同系统拥有一个完美的多任务处理器,即在系统中,每个进程将获得1/n的处理器时间---有n个可运行进程
完全公平调度(CFS)的做法是允许每个进程运行一段时间,循环轮转,选择运行最少的进程作为下个运行进程,而不是采用分配给每个进程时间片了
Linux调度的实现
- 时间记账
- 进程选择
- 调度器入口
- 睡眠和唤醒
调度器实体结构:CFS使用调度器实体结构来追踪进程运行记账
虚拟实时:vruntime变量存放进程虚拟运行时间,CFS使用vruntime变量来记录程序到底运行了多长时间以及还用运行多长时间
进程选择:CFS调度算法的核心----选择具有最小vruntime的任务
进程调度的主要入口点是schedule(),他正是内核其他部分用于调用进程调度器的入口:选择那个进程可以运行,何时将其投入运行
抢占和上下文切换
上下文切换:从一个可执行进程切换到另一个可执行进程,由context_switch()函数负责处理
该函数完成两项基本工作:
- 把虚拟内存从上一个进程映射切换到新进程中
- 从上一个进程的处理机状态切换到新进程的处理机状态
用户抢占发生的情况:
- 从系统返回用户空间时
- 从中断处理程序返回用户空间时
内核抢占发生的情况: - 中断处理程序郑正在执行,且返回内核空间之前
- 内核代码再一次具有可抢占性
- 内核中的任务显式的调用schedule()
- 内核中任务堵塞
实时调度策略
Linux提供了两种调度策略:
- SCHED_FIFO
- SCHED_RR
与调度相关的系统调用
系统调用可以用来操作和处理进程优先级,调度策略及处理器绑定,同时还提供了显式的将处理器交给其他进程的机制
与调度策略和优先级相关的系统调用:
- sched_setscheduler()和sched_getscheduler()分别用于设置和获取进程的调度策略和实时优先级
- sched_setparam()和sched_getparam()分别用于设置和获取进程的实时优先级
与处理器绑定相关的系统调用:
Linux调度程序提供强制的处理器绑定(processor affinity)机制
放弃处理器时间:Linux通过sched_yield()系统调用提供了一种让进程显式的将处理器时间让给其他等待执行进程的机制