进程调度算法详解

news2025/7/11 18:34:18

进程调度算法

    • 🏞️1. 调度指标
    • 🌁2. 先进先出(FIFO)
    • 🌠3. 最短作业优先(SJF)
    • 🌌4. 最短剩余时间优先(STCF)
    • 🌿5. 新度量指标:响应时间
    • 🍁6. 轮转(RR)
    • 🍃7. 优先级调度
    • ⛺8. 多级反馈队列(MLFQ)
      • 📖8.1 基本规则
      • 📖8.2 改变优先级
      • 📖8.3 当前MLFQ的一些问题
      • 📖8.4 提升优先级
      • 📖8.5 更好的计时方式

🏞️1. 调度指标

指标是我们用来衡量某些东西的东西,在进程调度中,有一些不同的指标是有意义的,现在,让我们来定义一个指标:周转时间. 任务的周转时间定义为任务的完成时间减去任务到达系统的时间,更正式的周转时间定义T周转时间是:T周转时间 = T完成时间 - T到达时间.

我们假设所有任务在同一时间到达,那么T到达时间 = 0,因此T周转时间 = T完成时间,随着放宽假设,这个情况将改变.

🌁2. 先进先出(FIFO)

我们可以实现的最基本的算法,被称为先进先出调度,也称为先到先服务.FCFS

FIFO有一些积极的特性:它很简单,而且易于实现.

我们来看一个简单的例子:假设有三个工作A,B,C在大致相同的时间到达系统,因为FIFO必须将某个工作放在前面,所以我们假设当它们都同时到达时,AB早一点点,然后BC早一点点,假设每个工作运行10s,这些工作的平均周转时间是多少?

image-20221115204445419

A在10s时完成,B在20s时完成,C在30s时完成,因此这三个任务的平均周转时间是(10 + 20 + 30)/ 3 = 20.

现在放宽假设,不再认为每个任务的运行时间相同,FIFO表现如何?

依然举一个例子:A运行100s,B和C运行10s.

image-20221115204836354

系统的平均周转时间是比较高的:(100 + 110 + 120) / 3 = 110.

这个问题通常被称为护航效应,一些耗时较少的潜在资源消费者被排在重量级的资源消费者之后.

总结:非抢占式的调度算法,按照请求的顺序进行调度,有利于长作业,但不利于短作业,因为短作业必须一直等待前面的长作业完毕才能执行,而长作业又需要执行很长时间,造成了短作业等待时间过长.

🌠3. 最短作业优先(SJF)

这个名称很容易记住,因为它完全描述了这个策略:先运行最短的任务,然后是次短的任务,如此下去.

我们用上面的例子,但以SJF作为调度策略,下图展示了A、B和C的结果,它清楚的说明了为什么在考虑平均周转时间的情况下,SJF调度策略更好,仅通过在A之前运行BCSJF将平均周转时间从110s降到了50s.

image-20221115205924668

事实上,考虑所有工作同时到达的假设,我们可以证明SJF确实是一个最优调度算法.

抢占式调度程序:在过去的批处理计算中,开发了一些非抢占式的调度程序,这样的系统会将每项工作做完,再考虑是否运行新工作,几乎所有现代化的调度程序都是抢占式的,非常愿意停止一个进程以运行另一个进程.

因此,现在我们假设工作可以随时到达,而不是同时到达,这导致了什么问题?

在这里我们可以再次用一个例子来说明问题,现在,假设A在t = 0时到达,且需要运行100s,而BCt = 10s时到达,且各需要运行10s,用纯SJF,得到如下图所示的调度:

image-20221115210655918

从图中可以看出,即使B和C在A不久后到达,它们仍然被迫等待A完成,从而遭遇同样的护航问题,这三项工作的平均周转时间103.33s,即(100 + (110 - 10) + (120 - 10)) / 3.

总结:非抢占式的调度算法,按估计运行时间最短的顺序进行调度.

长作业有可能会饿死,处于一直等待短作业执行完毕的状态,因为如果一直有短作业到来,那么长作业永远得不到调度.

🌌4. 最短剩余时间优先(STCF)

有一个调度程序是这样做的:向SJF添加抢占,称为最短剩余时间优先(STCF),每当新工作进入系统时,它就会确定剩余工作和新工作中,谁的剩余时间最少,然后调度该工作,因此,在我们的例子中,STCF将抢占A并运行BC,以完成,只有在它们完成后,才能调度A的剩余时间.

image-20221115211750822

🌿5. 新度量指标:响应时间

因此,如果我们知道任务长度,而且任务只使用CPU,而我们唯一的衡量是周转时间,STCF将是一个很好的策略. 事实上,对于许多早期批处理系统,这些类型的调度算法有一定的意义,然而,引入分时系统改变了这一切,现在,用户将会坐在终端前面,同时也要求系统的交互性好,因此,一个新的度量标准诞生了响应时间

响应时间定义为从任务到达系统到首次运行的时间,更正式的定义是:

T响应时间 = T首次运行 - T到达时间

🍁6. 轮转(RR)

轮转的基本思想很简单:RR在一个时间片(有时候称为调度量子)内运行一个工作,然后切换到运行队列的下一个任务,而不是运行一个任务直到结束. 它反复执行,直到所有任务完成,因此,RR有时被称为时间切片.

为了更详细的介绍RR,我们来看一个例子,假设三个任务A、B、C在系统中同时到达,并且它们都希望运行5s,SJF调度算法必须运行完当前任务才可以运行下一个任务,相比之下,1s时间片的RR可以快速的循环工作.

SJF(响应时间不好)

image-20221115213316301

轮转:

image-20221115213415605

RR的平均响应时间为(0 + 1 + 2)/ 3 = 1;SJF算法平均响应时间是(0 + 5 + 10)/ 3 = 5;

时间片长度对于RR是至关重要的,越短,RR在响应时间上表现越好,然而,时间片太短是有问题的:突然上下文切换的成本将影响整体性能,因此,系统设计者需要权衡时间片的长度,使其足够长,以便摊销上下文切换成本,而又不会使系统不及时响应.

总结:将所有就绪进程按FCFS的原则排成一个队列,每次调度时,把CPU时间分配给队首进程,该进程可以执行一个时间片,当时间片用完时,由计时器发出时钟中断,调度程序便停止该进程的执行,并将它送到就绪队列的末尾,同时继续把CPU时间分配给队首的进程.

🍃7. 优先级调度

为每个进程分配一个优先级,按优先级进行调度,为了防止低优先级的进程永远等不到调度,可以随着时间的推移增加等待进程的优先级.

⛺8. 多级反馈队列(MLFQ)

📖8.1 基本规则

1962年,Corbato首次提出多级反馈队列,应用于兼容时分共享系统(CTSS).

多级反馈队列需要解决两方面的问题:
首先,它要优化周转时间,这通过先执行短工作来完成,然而,操作系统通过不知道工作要运行多久,而这又是SJF(或STCF)等算法所必需的.

其次,MLFQ希望给交互用户很好的交互体验,因此,需要降低响应时间,然而,像轮转这样的调度算法虽然降低了响应时间,周转时间却很差.

MLFQ基本规则:

MLFQ中有许多独立的队列,每个队列有不同的优先级. 任何时刻,一个工作只能存在于一个队列中,MLFQ总是优先执行较高优先级的工作(即在较高级队列中的工作).

当然,每个队列中可能有多个工作,因此具有同样的优先级,在这种情况下,我们就对这些工作采用轮转调度.

因此,MLFQ调度策略的关键在于如何设置优先级,MLFQ没有为每个工作指定不变的优先级,而是根据观察到的行为调整它的优先级.

例如,如果一个工作不断放弃CPU去等待键盘输入,这是交互型进程的可能行为,MLFQ因此会让它保持高优先级,相反,如果一个工作长时间的占用CPU,MLFQ会降低其优先级,通过这种方式,MLFQ在进程运行过程中学习其行为,从而利用工作的历史来预测它未来的行为.

所以,我们得到了两条基本规则

  • 规则1:如果A的优先级 > B的优先级,运行A
  • 规则2:如果A的优先级 = B的优先级, 轮转运行A和B.

image-20221115223222727

但是存在这种情况:由于A和B具有最高优先级,调度程序将交替的调度它们,可怜的C和D永远都没有机会运行.

📖8.2 改变优先级

工作负载:既有运行时间很短,频繁放弃CPU的交互型工作,也有需要很多CPU时间、响应时间却不重要的长时间计算密集型工作.

所以,我们尝试优先级调整算法:

  • 规则3:工作进入系统时,放在最高优先级
  • 规则4a:工作用完整个时间片后,降低其优先级(移入下一个队列)
  • 规则4b:如果工作在其时间片以内主动放弃CPU,则优先级不变.

实例1:单个长工作

image-20221115224047257

该工作首先进入最高优先级,执行一个10ms的时间片后,调度程序将工作的优先级减一,因此进入Q1,在Q1执行一个时间片后,最终降低优先级进入系统的最低优先级,一直留在那里.

实例2:来了一个短工作

image-20221115224319892

A是一个长时间运行的CPU密集型工作,B是一个运行时间很短的交互型工作,假设A执行一段时间后B到达,会发生什么?

A(黑色)在最低优先级队列执行(长时间运行的CPU密集型工作),B(灰色)在时间T = 100时到达,并被加入最高优先级队列,由于它的运行时间很短,经过两个时间片,在被移入最低优先级队列之前,B执行完毕,然后A继续运行.

通过这个例子,大概体会到:如果不知道工作是短工作还是长工作,那么就在开始的时候假设其是短工作,并赋予最高优先级,如果确实是短工作,则很快会执行完毕,否则将被慢慢移入低优先级队列,而这时该工作也被认为是长工作了,通过这种方式:MLFQ近似于SJF.

实例3:如果有I/O呢?

image-20221115225253235

上图展示了这个运行过程,交互型工作 B(用灰色表示)每执行 1ms 便需要进行 I/O操作,它与长时间运行的工作 A(用黑色表示)竞争 CPU. MLFQ 算法保持 B 在最高优先级,因为 B 总是让出 CPU。如果 B 是交互型工作,MLFQ 就进一步实现了它的目标,让交互型工作快速运行.

📖8.3 当前MLFQ的一些问题

首先,会有饥饿(starvation)问题。如果系统有“太多”交互型工作,就会不断占用CPU,导致长工作永远无法得到 CPU(它们饿死了)。即使在这种情况下,我们希望这些长工作也能有所进展

其次,聪明的用户会重写程序,愚弄调度程序(game the scheduler)。愚弄调度程序指的是用一些卑鄙的手段欺骗调度程序,让它给你远超公平的资源。上述算法对如下的攻击束手无策:进程在时间片用完之前,调用一个 I/O 操作(比如访问一个无关的文件),从而
主动释放 CPU。如此便可以保持在高优先级,占用更多的 CPU 时间。做得好时(比如,每运行 99%的时间片时间就主动放弃一次 CPU),工作可以几乎独占 CPU.

📖8.4 提升优先级

让我们试着改变之前的规则,看能否避免饥饿问题。要让 CPU 密集型工作也能取得一些进展(即使不多),我们能做些什么?

一个简单的思路是周期性地提升(boost)所有工作的优先级:

  • 规则5:经过一段时间S,就将系统中所有工作重新加入最高优先级队列.

新规则一下解决了两个问题:

首先,进程不会饿死——在最高优先级队列中,它会以轮转的方式,与其他高优先级工作分享 CPU,从而最终获得执行。

其次,如果一个 CPU 密集型工作变成了交互型,当它优先级提升时,调度程序会正确对待它

📖8.5 更好的计时方式

现在还有一个问题要解决:如何阻止调度程序被愚弄?可以看出,这里的元凶是规则4a4b,导致工作在时间片以内释放 CPU,就保留它的优先级。那么应该怎么做?

  • 规则4:一旦工作用完了其在某一层中的时间配额(无论中间主动放弃多少次CPU),就降低其优先级.

image-20221115230400029

上图对比了在规则 4a、4b 的策略下(左图),以及在新的规则 4(右图)的策略下,同样试图愚弄调度程序的进程的表现。没有规则 4 的保护时,进程可以在每个时间片结束前发起一次 I/O 操作,从而垄断 CPU 时间。有了这样的保护后,不论进程的 I/O 行为如何,都会慢慢地降低优先级,因而无法获得超过公平的 CPU 时间比例

本章包含了一组优化的MLFQ规则:

  • 规则1:如果 A 的优先级 > B 的优先级,运行 A(不运行 B)
  • 规则2:如果 A 的优先级 = B 的优先级,轮转运行 A 和 B
  • 规则3:工作进入系统时,放在最高优先级(最上层队列)
  • 规则4:一旦工作用完了其在某一层中的时间配额(无论中间主动放弃了多少次CPU),就降低其优先级(移入低一级队列)
  • 规则5:过一段时间 S,就将系统中所有工作重新加入最高优先级队列

总结:一个进程需要执行100个时间片,如果采用时间片轮转调度算法,那么需要交换100
多级反馈队列是为这种需要连续执行多个时间片的进程考虑,它设置了多个队列,每个队列时间片大小都不同,进程在第一个队列没执行完,就会被移入到下一个队列,这种方式下,之前的进程只需要交换7
每个队列的优先级也不同,最上面的优先级最高,因此只有上一个队列没有进程在排队,才能调度当前队列上的进程.

可以将这种调度算法看成是时间片轮转调度算法和优先级调度算法的结合.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/8709.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux网络编程(四)多路I/O转接服务器

文章目录1.多路I/O转接服务器2.select 方式的多路I/O转接服务器3.poll 方式的多路I/O转接服务器4.epoll 方式的多路I/O转接服务器1.多路I/O转接服务器 多路IO转接服务器也叫做多任务IO服务器。该类服务器实现的主旨思想是,不再由应用程序自己监视客户端连接&#xf…

利用stream实现行政区域列表转tree树形结构

一、数据结构 CREATE TABLE t_districts (adcode bigint NOT NULL COMMENT 主键(区域编码)\r\n,pid varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT 父级区域编码,name varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci D…

MySQL的Redo log 、Undo log、 Binlog

MySQL的redo log 、undo log、 binlog redo log概念 redo log翻译过来叫重做日志,是一种保证持久化的措施,innodb存储引擎的物理日志文件 redo log是固定大小的,是循环写的过程 有了redo log之后,innodb就可以保证即使数据库发…

数据存储介绍

数据存储对象包括数据流在加工过程中产生的临时文件或加工过程中需要查找的信息。数据以某种格式记录在计算机内部或外部存储介质上。数据存储要命名,这种命名要反映信息特征的组成含义。数据流反映了系统中流动的数据,表现出动态数据的特征;…

STM32个人笔记-电源管理

笔记来源于STM32F103VET6,野火指南者,中文参考手册,HAL库开发手册和b站的野火指南者视频。观看过好多次了,但往往理解得不够全面,现记下小笔记,用来回顾。属于个人笔记。 电源监控器 STM32芯片主要通过VDD…

代码审计基础之SQL注入漏洞

1.SQL注入原理 SQL注入就是攻击者通过把恶意的SQL语句插入到Web表单的输入页面中,且插入的恶意语句会导致原有的SQL语句发生改变,从而达到攻击者的目的去让它执行一些危险的数据操作,进一步欺骗服务器去执行一些非本意的操作。 简单来讲&am…

Python BeautifulSoup4 入门使用

一、简介 BeautifulSoup4 与 lxml 一样,是一个 html 解析器,主要功能也是解析和提取数据。 BeautifulSoup4 是 爬虫 必学的技能。BeautifulSoup 最主要的功能是从网页抓取数据,Beautiful Soup 自动将输入文档转换为 Unicode 编码&#xff0c…

Verilog语言中case、casex、casez的用法和区别

casez与casex语句是case语句的两种变体, 在写testbench时用到。case 语句是一种多路条件分支的形式,可以解决 if 语句中有多个条件选项时使用不方便的问题。 一、case、casex、casez的区别 下表给出case、casex、casez的真值表: 1)在case语…

【计算机网络实验】防火墙访问控制列表实验

实验内容 防火墙访问控制列表实验 实验目的 理解访问控制列表的工作原理;了解访问控制列表的类型;学习标准访问控制列表的配置。 实验要求 1 实验拓扑图 本实验所用的网络拓扑如图1所示。 图1 ACL实验拓扑结构 2 实验步骤 Router0配置;&…

解决 npm install express 遇到的问题总结

方法1:权限 以管理员身份运行cmd执行npm install express --save命令 方法2:切换镜像源 查看镜像源 npm config get registry 如果要直接更换淘宝:npm config set registry https://registry.npmmirror.com/ 使用nrm切换 1.安装nrm npm i …

106362-34-9,(D-Ala1)-Peptide T amide

肽t的有效类似物DAPTA (aSTTTNYT-amide)在单核/巨噬细胞中显示出很强的抗hiv - 1活性,该肽抑制病毒的进入。 编号: 110545中文名称: 肽T、(D-Ala1)-Peptide T amide英文名: (D-Ala1)-Peptide T amideCAS号: 106362-34-9单字母: H2N-DAla-STTTNYT-NH2三字母: H2N-DAl…

设计模式 — 抽象工厂模式

抽象工厂模式女娲的失误实例 一实例 二抽象工厂模式的应用抽象工厂模式的优点抽象工厂模式的缺点抽象工厂模式的使用场景抽象工厂模式的注意事项女娲的失误 女娲造人的故事。人是造出来了,世界也热闹了,可是低头一看,都是清一色的类型&#…

Spark框架概述

Spark 框架概述 1.1. Spark是什么 定义:Apache Spark是用于大规模数据处理的统一分析引擎。 弹性分布式数据集RDD是一种分布式内存抽象,其使得程序员能够在大规模集群中做内存运算,并且有一定的容错方式。而这也是整个Spark的核心数据结构…

体验静态代码块

定义 public class Game {// 静态代码块static {System.out.println("static...run...");}// 构造方法public Game() {System.out.println("game...construct...");} }使用 结论 静态代码块在类被首次加载的时候触发启动

效能优化实践:C/C++单元测试万能插桩工具

研发效能是一个涉及面很广的话题,它涵盖了软件交付的整个生命周期,涉及产品、架构、开发、测试、运维,每个环节都可能影响顺畅、高质量地持续有效交付。在腾讯安全平台部实际研发与测试工作中我们发现,代码插桩隔离是单元测试工作…

theos tweak导入自定义类

有时,我们使用tweak的时候需要用到自定义的类,那么怎么引用呢? 假设我们有一个自定义类,people.h/people.m 那么分两种情况: 情况一,直接使用官方的tweak工程: 目录结构一般如下: …

[第九篇]——Docker 镜像使用

Docker 镜像使用 当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载。 下面我们来学习: 1、管理和使用本地 Docker 主机镜像2、创建镜像列出镜像列表 …

蛋白纯化-实验设计

小 M 不怕纯化“难”,IP、WB 只等闲。泡了两年实验室的小 M,理论与实操经验共有,且看我如何闯过蛋白纯化的几道“关”。 第一关 产品选择 小 M 敲黑板:此关最基础也最重要,谨防“一步错,步步错”。 亲和层析…

jenkins+junit4+allure+selenium实现自动化测试与结果可视化

安装包 jenkins.war jdk-8u332-linux-x64.tar.gz https://repo1.maven.org/maven2/io/qameta/allure/allure-commandline/2.17.2/ allure-commandline-2.17.2.zip https://chromedriver.storage.googleapis.com/index.html chromedriver 安装JDK 解压 tar xvf…

优盘数据恢复如何操作?恢复U盘数据的三个简单方法

对于我们用户来说,经常使用U盘来存储一些重要的文件是很常见的事。很多用户在使用的时候,经常因为操作不规范,而造成一些数据丢失。那么我们该如何做呢?优盘数据恢复如何操作?今天小编就来为大家分享一下关于如何将U盘…