进程调度,一个调度器的自白

2023-05-16

进程调度,一个调度器的自白

我是一个进程调度器。

我的职责是调度计算机内所有的进程,为他们分配 CPU 资源。

1、批处理时代

想当初,操作系统创造我时,只是打算让我用 FCFS 调度算法,简单维护下进程的秩序。但我后来的发展,远远超过了他的想象。

1.1 FCFS

所谓 FCFS 就是「先来先服务(First Come First Serve)」,每个进程按进入内存的时间先后排成一队。每当 CPU 上的进程运行完毕或者阻塞,我就会选择队伍最前面的进程,带着他前往 CPU 执行。

就拿这几个进程来说吧:

按照 FCFS 算法,我就会就按 A,B,C,D,E这样的顺序来将他们送往 CPU:

这一算法听起来简单又公平,然而好景不长,我收到了一个短进程的抱怨:”上次我前面排了一个长进程,等了足足 200 秒他才运行完。我只用 1 秒就运行结束了,就因为等他,我多花了这么长时间,太不值得了。”

我仔细一想, FCFS 算法确实有这个缺陷——短进程的响应时间太长了,用户交互体验会变差。

所以我决定,更换调度算法。

1.2 SPN

这次我设计的算法叫做「短任务优先」(Shortest Process Next,SPN)。每次选择预计处理时间最短的进程。因此,在排队的时候,我会把短进程从队列里提到前面。

这一次,短进程得到了很好的照顾,进程的平均响应时间大大降低,我和操作系统都很满意。

但长进程们不干了:那些短进程天天插队,导致他们经常得不到 CPU 资源,造成了「饥饿」现象。

取消 SPN 算法的呼声越来越高。

这可是个大问题。FCFS 虽然响应时间长,但最后所有进程一定有使用 CPU 资源的机会。但 SPN 算法就不一样了,如果短进程源源不断加入队列,长进程们将永远得不到执行的机会——太可怕了。

因此,短任务优先算法需要得到改进。有什么方法既能照顾短进程,又能照顾长进程呢?

1.3 HRRN

经过和操作系统的讨论,我们决定综合考量进程的两个属性:等待时间和要求服务时间——等待时间长,要求服务时间短(就是短进程)的进程更容易被选中。

为了量化,我们制定了一个公式:响应比 = (等待时间+要求服务时间)/ 要求服务时间。响应比高的算法会先执行。我们称之为「高响应比优先」(Highest Response Ratio Next,HRRN)。

这个算法得到了长短进程的一致好评。虽然我的工作量增加了(每次调度前,我都要重新计算所有等待进程的响应比)但为了进程们的公平性,这一切都是值得的。

2、并发时代

新时代到了。

随着计算机的普及,个人用户大量增长,并发,即一次运行多个程序的需求出现了。这可难倒我了——处理器只有一个,怎么运行多个程序?

所幸 CPU 点醒了我:“我现在的运算速度既然这么快,何不发挥这项长处,弄一个「伪并行」出来?“

“伪并行?什么意思”

“就是看起来像并行,实际上还是串行。每个进程短时间交替使用我的资源,但在人类看来,这些进程就像在「同时」运行。”

我恍然大悟。

2.1 RR

经过 CPU 的提醒,我很快制定出了新的调度算法——时间片轮转算法(Round Robin,RR)。

在这个算法里,每个进程将轮流使用 CPU 资源,只不过在他们开始运行时,我会为他们打开定时器,如果定时器到时间(或者执行阻塞操作),进程将被迫「下机」,切换至下一个进程。至于下一个进程的选择嘛,直接用 FCFS 就好了。

新的算法必然会面临新的问题,现在我的问题就是,时间片的长度怎么设计?

直观来看,时间片越短,固定时间里可运行的进程就越多,可 CPU 说过,切换进程是要消耗他不少指令周期的,时间片过短会导致大量 CPU 资源浪费在切换上下文上。时间片过长,短交互指令响应会变慢。所以具体怎么取,还得看交互时间大小(感觉像没说一样,但至少给了个标准嘛)。

这一阶段,我的工作量大大提升——以前十几秒都不用切换一次程序,现在倒好,一秒钟就得切换数十次。

2.2 VRR

时间片轮转算法看起来十分公平——所有的进程时间片都是一样的。但事实真是这样吗?

I/O 密集型进程不这么认为,他对我说:“调度器大哥,时间片轮转没有照顾到我们这类进程啊!我们经常在 CPU 没呆到一半时间片,就遇到了阻塞操作,被你赶下去。而且我们在阻塞队列,往往要停留很长时间。等阻塞操作结束,我们还得在就绪队列排好长时间队。那些处理器密集型进程,使用了大部分的处理器时间,导致我们性能降低,响应时间跟不上”

考虑到这些进程的要求,我决定为他们创建一个新的辅助队列。阻塞解除的进程,将进入这个辅助队列,进行进程调度时,优先选择辅助队列里的进程。

这就是「虚拟轮转法」(Virtual Round Robin,VRR)。

从后来实际性能结果来看,这种方法确实优于轮转法。我颇为自豪。

2.3 优先级调度

有一天,操作系统忽然找到我,神神秘秘的说:“调度器啊,你是知道的,我要给整个系统提供服务,可最近用户进程太多,导致我的服务进程有时候响应跟不上。我有点担心这会给系统稳定性造成影响。”

我一听,这可是个大事,系统不稳定那还得了?调度算法得换!

既然要让操作系统的服务得到足够的运行资源,那就,干脆让他们具有最高的 CPU 使用优先权吧。

优先级调度算法就此产生了。

我向大家做出了规定——每个进程将被赋予一个优先级,自己根据自己的情况确定优先级数值,但是,用户进程的优先级不准高于内核进程的优先级。

切换程序的时候,我会从优先级 1 的队列里选择一个进程,如果优先级 1 队列为空,才会选择优先级 2 中的进程,以此类推。

当然,为了保证低优先级进程不会饥饿,我会调高等待时间长的进程的优先级。

使用这个算法,我更忙碌了,不仅需要大量切换进程,还需要动态调节优先级。可能这就是能力越大,责任越大吧。

不过我知道,正是因为我的存在,人类才能在计算机上运行多道程序——这令我感到自豪。

希望你在看完我的文章之后有所收获。


 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

进程调度,一个调度器的自白 的相关文章

  • leetcode刷题6.16 树的层序遍历,树的序列化

    给你一个二叉树 xff0c 请你返回其按 层序遍历 得到的节点值 xff08 即逐层地 xff0c 从左到右访问所有节点 xff09 示例 xff1a 二叉树 xff1a 3 9 20 null null 15 7 3 9 20 15 7
  • 深度优先及广度优先算法

    深度优先搜索算法DFS 广度优先搜索算法BFS 在猪呢个算法知识点中占比非常大 xff0c 应用最多的地方是对图进行遍历 xff08 树以为是图的一种 xff09 深度优先搜索算法DFS DFS解决的 是连通性的问题 xff0c 及给定两个
  • 厄拉多塞筛法 快速求质数 /回文子串

    西元前250年 xff0c 希腊数学家厄拉多塞 Eeatosthese 想到了一个非常美妙的质数筛法 xff0c 减少了逐一检查每个数的的步骤 xff0c 可以比较简单的从一大堆数字之中 xff0c 筛选出质数来 xff0c 这方法被称作厄
  • Docker部署Sonarqube

    1 下载镜像 docker pull registry span class token punctuation span cn span class token operator span shenzhen span class toke
  • leetcode刷题 旋转链表

    92 反转链表 II 难度中等393 反转从位置 m 到 n 的链表 请使用一趟扫描完成反转 说明 1 m n 链表长度 示例 输入 1 gt 2 gt 3 gt 4 gt 5 gt NULL m 61 2 n 61 4 输出 1 gt 4
  • 分布式实时处理系统——C++高性能编程 RAII resource acquisition is initialization

    分布式实时处理系统 C 43 43 高性能编程 前言 基于通信基础 xff0c 介绍Hurricane实时处理系统的工程实现 xff0c 主要使用C 43 43 语言 一 IPC socket 异步I O epoll 二 C 43 43 1
  • 6月21 刷题思考

    1 RALL相关知识点 2 std set的使用 xff1f xff1f 不熟练 3 一个无序整数数组中找到最长连续序列 4 Two Sum 问题 Data structure design 5 i 43 43 在两个线程里边分别执行100
  • V2X就是Vehicle To Everything 国标中有五种消息BSM、RSI、RSM、SPAT、MAP

    前面讲到V2X就是Vehicle To Everything xff0c 即车队外界所有信息的交换 xff0c 这里的X代表Everything xff0c 在V2X概念中 xff0c 我们将它看作四大部分 xff0c 车与车通信 xff0
  • 6月23 leetcode 二进制求和

    67 二进制求和 难度简单404收藏分享切换为英文关注反馈 给你两个二进制字符串 xff0c 返回它们的和 xff08 用二进制表示 xff09 输入为 非空 字符串且只包含数字 1 和 0 示例 1 输入 a 61 34 11 34 b
  • 利用栈实现树的中序遍历

    94 二叉树的中序遍历 难度中等537收藏分享切换为英文关注反馈 给定一个二叉树 xff0c 返回它的中序 遍历 示例 输入 1 null 2 3 1 2 3 输出 1 3 2 进阶 递归算法很简单 xff0c 你可以通过迭代算法完成吗 x
  • STL中的set详解

    1 关于set C 43 43 STL 之所以得到广泛的赞誉 xff0c 也被很多人使用 xff0c 不只是提供了像vector string list等方便的容器 xff0c 更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构
  • 你真的了解二分查找吗?

    传统的二分查找算法 提到二分查找 xff0c 相信很多人都不陌生 xff0c 大学学数据结构的时候老师都讲过 xff0c 它是一种效率较高的查找方法 xff0c 基于顺序存储结构的线性表 xff0c 且要求表中元素按关键字有序排列 假设元素
  • 二叉树DFS/BFS实现(C++)

    深度优先搜索算法 xff08 Depth First Search xff09 DFS是搜索算法的一种 它沿着树的深度遍历树的节点 xff0c 尽可能深的搜索树的分支 当节点v的所有边都己被探寻过 xff0c 搜索将回溯到发现节点v的那条边
  • 当TCP建立连接过程中出现问题了,如何检查?

    netstat命令 stat状态说明 TCP协议规定 xff0c 对于已经建立的连接 xff0c 网络双方要进行四次握手才能成功断开连接 xff0c 如果缺少了其中某个步骤 xff0c 将会使连接处于假死状态 xff0c 连接本身占用的资源

随机推荐

  • 本地服务器上传代码到gitee仓库

    把gitlab仓库里的node day01项目传到本地服务器 再把本地服务器里的node day01项目传到Gitee代码仓库 1 登录Gitlab xff0c 复制代码仓库地址 2 拷贝一刚复制的Git 仓库到本地 root 64 ubu
  • 牛客网刷刷刷刷

    作者 xff1a 故事的小黄瓜 链接 xff1a https www nowcoder com discuss 436386 来源 xff1a 牛客网 1 xff0e 线程池如何开启一个新线程 xff1f 2 xff0e 线程池初始化的步骤
  • c++ 后端linux开发常见问题

    计算机操作系统 xff08 Linux xff09 命令 xff1a netstat tcpdump ipcs ipcrm 这四个命令的熟练掌握程度基本上能体现实际开发和调试程序的经验 cpu 内存 硬盘 等等与系统性能调试相关的命令必须熟
  • STL c++ 使用小结

    各位看官 xff0c 欢迎来到趁热搬砖小码农的博客 在写C 43 43 程序的时候会发现STL是一个不错的东西 xff0c 减少了代码量 xff0c 使代码的复用率大大提高 xff0c 减轻了程序猿的负担 还有一个就是容器 xff0c 你会
  • Oracle面试题,带答案!

    1 你要对操纵Oracle数据库中的数据 下列哪个选项表示Oracle中select语句的功能 xff0c 并且不需要使用子查询 xff08 C xff09 A xff0e 可以用select语句改变Oracle中的数据 B xff0e 可
  • 什么是进程?什么是线程?总结

    1 什么是进程 xff1f 什么是线程 xff1f 进程是表示资源分配的基本单位 xff0c 又是调度运行的基本单位 例如 xff0c 用户运行自己的程序 xff0c 系统就创建一个进程 xff0c 并为它分配资源 xff0c 包括各种表格
  • C++知识点小结(趁热搬砖三年半的小码农) 2020年07月2日整理

    c 43 43 最好用易用的新特性 xff1a auto decltype https blog csdn net zyc2018 article details 93591189nullptr range forusing c 43 43
  • 如何定位内存泄漏问题

    如何定位内存泄漏问题 Things You 39 ll Need Proficiency in C 43 43 C 43 43 compilerDebugger and other investigative software tools
  • C++之future和promise

    C 43 43 之future和promise future和promise的作用是在不同线程之间传递数据 使用指针也可以完成数据的传递 xff0c 但是指针非常危险 xff0c 因为互斥量不能阻止指针的访问 xff1b 而且指针的方式传递
  • linux常用小知识点

    答案linux考试题 1 在登录Linux时 xff0c 一个具有唯一进程ID号的shell将被调用 xff0c 这个ID是什么 b A NID B PID C UID C CID 答 xff1a w命令查看用户tty终端信息 ps ef
  • 无锁编程基础

    背景 我们处在技术快速发展的时代 xff0c 竞争变得前所未有的激烈 xff0c 不仅要十八般武艺俱全 xff0c 还得选对正确的技术 xff0c 跟上发展的脚步 xff0c 并贴上精研某个专业方向的标签 我们不仅要面对多线程和并发 xff
  • Linux网络相关概念和修改IP地址的方法

    网卡的命名规则 ifconfig xff1a 用于显示或设置网络设备 ens32 span class token punctuation span flags span class token operator 61 span span
  • 二维坦克大战游戏代码开发

    这是我实际面试中 xff0c 遇到的一个题目 xff0c 编写一个坦克大战游戏 一开始感觉懵 xff0c 后来代码写写就好了 include lt iostream gt include lt stdlib h gt include lt
  • 软件系统性能常识

    不管是系统设计人员 开发人员还是测试人员 xff0c 要构建高性能的系统 xff0c 对于系统性能的一些常用术语都不了解 xff0c 那是无从做起的 xff0c 这里主要介绍几个软件性能指标的术语及计算方法 xff0c 便以在性能优化及性能
  • Socket的三种轮询方式select、poll、epoll之间的区别

    select poll epoll之间的区别 搜狗面试 1 select 61 61 gt 时间复杂度O n 它仅仅知道了 xff0c 有I O事件发生了 xff0c 却并不知道是哪那几个流 xff08 可能有一个 xff0c 多个 xff
  • linux后端c++开发人员需要学习的技术栈

    数据结构和算法 学完之后要刷leetcode xff08 剑指offer xff09 计算机网络 tcp ip 协议栈 xff08 tcp ip详解 xff09 操作系统 进程和线程 并发 和锁 内存分布调度等等 xff08 深入理解操作系
  • 内核态和用户态的区别

    内核态和用户态的区别 当一个任务 进程 执行系统调用而陷入内核代码中执行时 xff0c 我们就称进程处于内核状态 此时处理器处于特权级 最高的 0级 内核代码 当进程处于内核态时 xff0c 执行的内核代码会使用当前的内核栈 每个进程都有自
  • Linux查找命令四剑客awk、sed、find(locate)、grep讲解

    目录 find命令 xff1a 一旦执行了chmod 000 那么如何恢复权限呢 xff1f 2 grep xff08 找文件内容 行操作 xff09 3 awk 4 sed 找文件内容 行操作 find命令 xff1a 1 find xf
  • go语言学习笔记,特点

    1 并发编程 Go语言在并发编程方面比绝大多数语言要简洁不少 xff0c 这一点是其最大亮点之一 xff0c 也是其未来进入高并发高性能场景的重要筹码 golang的并发执行单元是一种称为goroutine的协程 协程又称为微线程 xff0
  • 进程调度,一个调度器的自白

    进程调度 xff0c 一个调度器的自白 我是一个进程调度器 我的职责是调度计算机内所有的进程 xff0c 为他们分配 CPU 资源 1 批处理时代 想当初 xff0c 操作系统创造我时 xff0c 只是打算让我用 FCFS 调度算法 xff