什么是进程调度,进程调度的来龙去脉

多道程序设计的目标是,无论何时都有进程运行,从而最大化 CPU 利用率。分时系统的目的是在进程之间快速切换 CPU,以便用户在程序运行时能与其交互。

为了满足这些目标,进程调度器选择一个可用进程(可能从多个可用进程集合中)到 CPU上执行。如果有多个进程,那么余下的需要等待 CPU 空闲并能重新调度。

调度队列

进程在进入系统时,会被加到作业队列,这个队列包括系统内的所有进程。驻留在内存中的、就绪的、等待运行的进程保存在就绪队列上。

就绪队列通常用链表实现;其头节点有两个指针,用于指向链表的第一个和最后一个 PCB 块;每个 PCB 还包括一个指针,指向就绪队列的下一个 PCB,如图 1 所示。

系统还有其他队列。当一个进程被分配了 CPU 后,它执行一段时间,最终退出,或被中断,或等待特定事件发生如 I/O 请求的完成。假设进程向一个共享设备如磁盘发出 I/O 请求。由于系统具有许多进程,磁盘可能忙于其他进程的 I/O 请求,因此该进程可能需要等待磁盘。等待特定 I/O 设备的进程列表,称为设备队列。每个设备都有自己的设备队列(图 1)。

就绪队列和各种I/O设备队列
图 1 就绪队列和各种I/O设备队列

进程调度通常用队列图来表示,如图 2 所示。每个矩形框代表一个队列;这里具有两种队列:就绪队列和设备队列。圆圈表示服务队列的资源;箭头表示系统内的进程流向。

表示进程调度的队列图
图 2 表示进程调度的队列图

最初,新进程被加到就绪队列;它在就绪队列中等待,直到被选中执行或被分派。当该进程分配到 CPU 并执行时,以下事件可能发生:
  • 进程可能发出 I/O 请求,并被放到 I/O 队列。
  • 进程可能创建一个新的子进程,并等待其终止。
  • 进程可能由于中断而被强制释放 CPU,并被放回到就绪队列。

对于前面两种情况,进程最终从等待状态切换到就绪状态,并放回到就绪队列。进程重复这一循环直到终止;然后它会从所有队列中删除,其 PCB 和资源也被释放。

调度程序

进程在整个生命周期中,会在各种调度队列之间迁移。操作系统为了调度必须按一定方式从这些队列中选择进程。进程选择通过适当调度器或调度程序来执行。

通常,对于批处理系统,提交的进程多于可以立即执行的。这些进程会被保存到大容量存储设备(通常为磁盘)的缓冲池,以便以后执行。长期调度程序(或作业调度程序)从该池中选择进程,加到内存,以便执行。短期调度程序(或 CPU 调度程序)从准备执行的进程中选择进程,并分配 CPU。

两种调度程序的主要区别是执行频率:
  • 短期调度程序必须经常为 CPU 选择新的进程。进程可能执行几毫秒,就会等待 I/O 请求。通常,短期调度程序每 100ms 至少 执行一次。由于执行之间的时间短,短期调度程序必须快速。如果花费 10ms 来确定执行一个运行 100ms 的进程,那么 10/(100 + 10) = 9% 的 CPU 时间会用(浪费)在调度工作上。
  • 长期调度程序执行并不频繁;在新进程的创建之间,可能有几分钟间隔。长期调度程序控制多道程序程度(内存中的进程数量)。如果多道程序程度稳定,那么创建进程的平均速度必须等于进程离开系统的平均速度。因此,只有在进程离开系统时,才需要长期调度程序的调度。由于每次执行之间的更长时间间隔,长期调度程序可以负担得起更多时间,以便决定应该选择执行哪个进程。

重要的是,长期调度程序进行认真选择。通常,大多数进程可分为 I/O 为主或 CPU 为主,I/O 密集型进程执行 I/O 比执行计算需要花费更多时间。相反,CPU 密集型进程很少产生 I/O 请求,而是将更多时间用于执行计算。

长期调度程序应该选择 I/O 密集型和 CPU 密集型的合理进程组合。因为如果 所有进程都是 I/O 密集型的,那么就绪队列几乎总是为空,从而短期调度程序没有什么可做。如果所有进程都是 CPU 密集型的,那么 I/O 等待队列几乎总是为空,从而设备没有得到使用,因而系统会不平衡。

有的系统,可能没有或极少采用长期调度程序。例如,UNIX 或微软 Windows 的分时系统通常没有长期调度程序,只是简单将所有新进程放于内存,以供短期调度程序使用。这些系统的稳定性取决于物理限制(如可用的终端数)或用户的自我调整。如果多用户系统性能下降到令人难以接受,那么有的用户就会退出。

有的操作系统如分时系统,可能引入一个额外的中期调度程序,如图 3 所示。

添加中级进程调度到队列图
图 3 添加中级进程调度到队列图

中期调度程序的核心思想是可将进程从内存(或从 CPU 竞争)中移出,从而降低多道程序程度。之后,进程可被重新调入内存,并从中断处继续执行。这种方案称为交换

通过中期调度程序,进程可换出,并在后来可换入。为了改善进程组合,或者由于内存需求改变导致过度使用内存从而需要释放内存,就有必要使用交换。

上下文切换

前面提过,中断会导致 CPU 从执行当前任务改变到执行内核程序。这种操作在通用系统中经常发生。当中断发生时,系统需要保存当前运行在 CPU 上的进程的上下文,以便在处理后能够恢复上下文,即先挂起进程,再恢复进程。

切换 CPU 到另一个进程需要保存当前进程状态和恢复另一个进程的状态,这个任务称为上下文切换

当进行上下文切换时,内核会将旧进程状态保存在其 PCB 中,然后加载经调度而要执行的新进程的上下文。上下文切换的时间是纯粹的开销,因为在切换时系统并没有做任何有用工作。上下文切换的速度因机器不同而有所不同,它依赖于内存速度、必须复制的寄存器数量、是否有特殊指令(如加载或存储所有寄存器的单个指令)。典型速度为几毫秒。

上下文切换的时间与硬件支持密切相关。例如,有的处理器(如 Sun UltraSPARC)提供了多个寄存器组,上下文切换只需简单改变当前寄存器组的指针。当然,如果活动进程数量超过寄存器的组数,那么系统需要像以前一样在寄存器与内存之间进行数据复制。

不仅如此,操作系统越复杂,上下文切换所要做的就越多,高级的内存管理技术在每次上下文切换时,所需切换的数据会更多。例如,在使用下一个进程的地址空间之前,需要保存当前进程的地址空间。如何保存地址空间,需要做什么才能保存等,取决于操作系统的内存管理方法。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


起步 处理器架构,参考 x86是指intel的开发的一种32位指令集 intel和amd早期的cpu都支持这种指令集 AMD比Intel率先制造出了商用的兼容x86的CPU,AMD称之为AMD64 Intel选择了设计一种不兼容x86的全新64为指令集,称之为IA-64,后来支持AMD64的指令集,
pscp pscp -P 22 C:\work\test.txt root@192.168.1.5:/home/data pscp -P 22 root@192.168.1.5:/home/data/test.txt C://work// 检索 find / -name default.config
文件处理 ls -a # 显示所有文件 ls -l # 显示详细信息 ls -d # 显示路径 mkdir /目录名称 # 创建目录 cd /目录名称 # 切换目录 pwd # 显示当前路径 rmdir /目录名称 # 删除目录 cp -rp [目录名称] [目标目录] # 复制目录到目标目录 cp
准备一台电脑(我就用联想拯救者r7000演示) 参考博客制作启动盘 插上U盘,启动电脑,一直按F2 进入如下页面后,将U盘设置为第一启动项,点击exit,保存并退出 之后进入如下页面,选择第三项 进入如下页面,选择第四项 进入如下页面,选择第一项,选中后,先不要点Enter 按e键,将inst.st
认识 Linux系统是参考了UNIX系统作为模板开发的,但没有使用UNIX的代码;是UNIX的一种,但不是衍生版 在Linux内核的基础上开发是发行版 分区 逻辑分区永远从5开始 步骤 挂载:可理解为分配盘符,挂载点即是盘符名;不同之处:Linux中是以空目录名称作为盘符 Hda 第一块硬盘 Hda
文件处理命令 以 . 开头的文件是隐藏文件 以 - 开头表示这是一个文件 以 d 开头表示是一个目录 以 l 开头表示是一个软链接 第一个root是所有者,第二个root是所属组 ls -h 以文件默认大小后缀 显示 ls -i 查看i节点(唯一标识) 所有者:只能有一个,可变更 所属组:只能有一个
参考 01 02 03 前提环境 本地安装VirtualBox,并安装CentOS8,配置网络后,window系统上putty能连接到CentOS8服务器 配置步骤 右键服务器复制 启动复制后的服务器,查看ip和hostname发现和原来的服务器一样,需要修改 hostname # 查看主机名 vi
文件搜索命令 星号匹配任意字符,问号匹配任意单个字符 -iname 根据文件名查找且不区分大小写 -ok 命名会有一个询问的步骤 如果没有找到指定文件,可输入命令:updatedb 更新文件资料库;除tmp目录不在文件资料库收录范围之内 locate -i 文件名 # 检索时不区分大小写 which
安装环境 安装最新版的Virtual Box,点击安装 下载centos8镜像 创建虚拟机,可参考 选择下载到本地的镜像 设置启动顺序 点击启动 启动过程中报错:“FATAL:No bootable medium found!” 1.没有选择iso镜像 2.光驱没有排在第一位置 3.镜像只能选择x8
Linux严格区分大小写 所有内容文件形式保存,包括硬件 Linux不靠扩展名区分文件类型 挂载:将设备文件名和挂载点(盘符)连接的过程 Linux各个目录的作用 bin表示二进制 服务器注意事项 远程服务器不允许关机,只能重启 重启时应该关闭服务 不要在服务器访问高峰运行高负载命令 远程配置防火墙
IDE连接Linux,上传下载文件 参考1 参考2 连接Linux 上传下载文件 本地项目打包后上传 查看是否上传成功,右键下载 补充 后端项目开发完成后,需clean掉临时文件target文件夹,且只推送修改过的文件 前端项目开发的过程中,需要在每个子组件中使用scoped,确保每个子组件中的编码
起步 LTS与普通版本的区别 LTS版本的发布周期更长,更加稳定 安装jdk sudo mkdir /usr/lib/jvm # 在Ubuntu中创建目录 pscp D:\安装包\linux源码包\jdk-8u291-linux-x64.tar.gz chnq@192.168.0.102:/tmp
前言 最近在b站上看了兄弟连老师的Linux教程,非常适合入门:https://www.bilibili.com/video/BV1mW411i7Qf 看完后就自己来试着玩下,正好手上有台空闲的电脑就尝试不使用虚拟机的方式安装Linux系统 安装步骤 制作启动盘 下载ISO镜像,我这里下载的是Cen
新建虚拟电脑 设置内存和处理器 设置硬盘大小 完成 设置 查看光驱 设置启动顺序 点击启动 选择第1项 进入图形安装界面 选择安装位置,开始安装 设置root密码 重启 登录 查看本地文件夹 配置网络,点击设置 查看宿主机ip C:\Users\ychen λ ipconfig 无线局域网适配器 W
源码包安装需手动下载后安装 二进制包则在package目录下 rpm命令管理rpm包 若某个rpm包依赖于某个模块,需要到网站www.rpmfind.net查询该模块依赖的包,安装这个包后自动安装模块,之后就能安装rpm包了 安装升级时使用包全名 查询卸载时使用包名 虚拟机中的Linux系统安装rp
首先进入命令模式,再输入以下命令 命令模式用于输入命令 插入模式可对文件编写操作 编辑模式下的命令是在冒号后输入 :12, 15d # 删除指定范围的行,这里是删除12到15行 :n1,n2s/old/new/g ## 表示从n1行到n2行,old表示旧的字符串 vim使用小技巧:自定义快捷键,如快
使用源码包安装,需要自己指定安装位置,通常是 /usr/local/软件名/ linux中要想启动执行文件,应使用绝对路径 /绝对路径/rpm包名 start ## 执行方式一 service rpm包名 start ## 执行方式二 使用源码包安装后,由于自定义安装路径,就不能使用service命
网络命令 在收邮件的用户中,输入 mail 可查看邮件信息,输入序列号查看详细信息 在mail命令下,输入h 查看所有邮件的列表 输入:d 序列号 # 删除邮件 last # 统计所有用户登录或重启时间,用于日志查询 lastlog # 显示包括未登录用户的登录时间 lastlog -u 用户id
若要使用yum管理,必须能连接网络,首先配置网络IP 进入yum源文件中启动容器 使用yum源头安装rpm包不需要进入package路径,同时也不需要使用包全名,会有yum自动管理 安装软件组
简介 client即是本机安装的docker,相当于git Docker_host相当于centos系统 registry则是docker仓库,相当于GitHub 镜像用于创建docker容器,一个镜像可以创建多个docker容器 容器是由镜像创建的运行实例,(镜像相当于类,容器相当于类创建的对象)