进程调度的时机,切换与过程方式(操作系统OS)

核心比喻:CPU是一位超级全能的打工人

想象一下,CPU 就是一个办公室里唯一的一位超级打工人 ,他一次只能处理一件任务。而进程(Process)就是他需要处理的一件件具体任务,比如"写A项目的报告"、"做B项目的PPT"、"回复C客户的邮件"等等。

办公室里还有个工头(操作系统) ,他负责管理这位打工人,决定他下一个小时、下一分钟应该干什么活。这个决定过程,就叫做"进程调度"

好,带着这个比喻,我们来逐一拆解视频里的知识点。


1. 什么时候需要安排新工作?(进程调度的时机)

工头什么时候会介入,让打工人换个任务呢?

  • 打工人主动要求换(主动放弃)

    • 任务完成了:打工人说:"A项目的报告我写完了!" (进程正常终止)
    • 任务出错了:打工人说:"写报告的软件崩溃了,这活干不下去了!" (发生异常终止)
    • 需要等别人:打工人说:"我需要等设计部把图片发给我,才能继续做PPT。我先等着,你安排点别的活吧。" (进程发出I/O请求,比如读写文件、等待网络数据,进入阻塞状态)
  • 工头强制他换(被动放弃)

    • 时间到了:工头说:"A报告你已经写了10分钟了,按规定该轮到B任务了,先停下!" (分配的时间片用完)
    • 有更急的活:工头突然冲过来说:"别写报告了!大老板要的紧急数据清单来了,马上做这个!" (有优先级更高的进程进入就绪队列)

2. 什么时候绝对不能打扰他?(不能进行进程调度的情况)

虽然工头可以随时换任务,但有些特殊时刻,是绝对不能打扰这位打工人的,否则会出大事。

  • 正在处理紧急情况时(处理中断过程中)

    • 比喻:办公室的火警响了!打工人正在按照紧急预案进行操作(比如关闭电闸、保存关键数据)。这时候工头跑过来说"别管火警了,快来做PPT",这显然是不行的。中断处理就像处理火警一样,是十万火急的、流程固定的,必须一气呵成。
  • 正在整理"任务总清单"时(在操作系统内核程序临界区中)

    • 比喻:工头有一本"所有任务状态"的总账本(这就是内核数据,比如就绪队列)。打工人正在帮工头整理这个账本,比如把"已完成"的任务划掉,把"新来的"任务加上。在他整理到一半时(比如刚把A任务划掉,还没把B任务加上),如果工头强制他去干别的,那这个总账本就乱了,整个办公室的管理都会出问题。
    • 所以,当进程在访问这种核心管理数据 时,会先"锁门",告诉工头"别催,等我弄完这个再说",这就是内核临CRITICAL区,不能调度。
  • 正在做"一笔转账"时(原子操作过程中)

    • 比喻 :打工人的任务是从A账户转100元到B账户。这个操作分两步:1. A账户减100元;2. B账户加100元。这两步必须连续完成,不可分割。如果在第1步完成后打断他,A的钱少了,B的钱没多,那100块钱就凭空消失了!这种必须一气呵成、不能被打断的操作,就叫原子操作

3. "核心区"和"普通区"有啥区别?(内核临界区 vs 普通临界区)

  • 内核程序临界区 :就像上面说的,是访问**"办公室管理总账本"的地方。如果在这里被打断,会影响到整个办公室的运作**。所以,为了保证管理不出错,不允许调度。

  • 普通临界区 :是访问**"公共打印机"这样的地方。比如,A任务正在打印一份100页的文件,B任务也想打印。这时候,B任务只能等着。但是,在A任务等待打印机慢慢吐纸的这个漫长时间里,我们的超级打工人(CPU)闲着也是闲着,工头(操作系统)完全可以让他 先去做别的任务**,比如回个邮件。这并不会影响办公室的管理,反而提高了打工人的利用率

总结一下:进"核心区"是为了修改系统核心数据,不能打扰;进"普通区"是为了使用一个共享设备,可以趁等待的功夫去干点别的。

4. 安排工作的方式(进程调度的方式)

工头安排工作有两种风格:

  • "绅士"风格(非剥夺/非抢占式)

    • 工头把一个任务交给打工人后,就完全信任他。除非打工人自己说"我干完了"或者"我需要等待",否则工头绝不打扰。哪怕此时来了更紧急的任务,工头也得等着。
    • 优点:管理简单,工头省心(系统开销小)。
    • 缺点:无法处理急事,万一一个任务占着不放,紧急任务就得一直等。
    • 适用场景:早期的批处理系统,大家排好队,一个一个来。
  • "霸道总裁"风格(剥夺/抢占式)

    • 工头有绝对的权威。他可以随时根据情况,强行中断打工人当前的任务,让他去做更重要的事。比如"这个任务你先干10分钟",10分钟一到,立刻换人;或者"停下,那个更急!"
    • 优点:能及时响应紧急任务,用户体验好。
    • 缺点:工头得频繁介入,管理开销大。
    • 适用场景:我们现在用的电脑和手机(分时操作系统),以及需要快速响应的工业控制系统(实时操作系统)。

5. "决定"和"执行"是两回事(进程调度 vs 进程切换)

这一点很容易混淆,我们再用比喻说清楚:

  • 进程调度:是**"决策"过程**。工头看着手里的任务清单,思考了一下,说:"好了,下一个让打工人去做B任务!" 这个**"决定谁上"的思考动作**,就是调度。

  • 进程切换 :是**"执行"过程**。在工头做出决定后,如果决定要换一个新任务,打工人就需要:

    1. 把他正在做的A任务的所有资料、进度(比如报告写到第几页了,思路是什么)都整理好,存档(保存旧进程的现场)。
    2. 拿出 B任务的资料,看看上次做到哪了,然后铺开准备继续干(恢复新进程的现场)。
    • 这套"收拾东西、拿出新东西"的动作,就是进程切换

关键区别:调度是"动脑",切换是"动手"。如果工头调度后决定"嗯,继续做A任务吧",那就只有调度,没有切换。只有当决定要换任务时,才会发生切换。

6. 换工作的具体流程(进程切换的过程)

上面说的"收拾东西、拿出新东西"具体是怎么回事呢?

每个任务(进程)都有一个**"档案袋"(进程控制块 PCB)**。里面装着关于这个任务的一切信息:任务ID、任务状态、做到哪一步了(CPU寄存器里的数据)、需要哪些资源等等。

进程切换的过程就是:

  1. 保存现场:把当前任务A的所有进度信息,从CPU的"大脑"里拿出来,完整地存到任务A的"档案袋"(PCB)里。
  2. 恢复现场:从即将要执行的任务B的"档案袋"(PCB)里,把它上次的全部进度信息,加载到CPU的"大脑"里。

这样,CPU就能无缝衔接,好像从未离开过任务B一样。

代价 :这个"存取档案"的过程是需要花费时间的。如果工头让打工人每分钟切换80次任务,那他可能光收拾和拿东西了,真正干活的时间就很少了。所以,过于频繁的进程切换会降低整个系统的效率。


相关推荐
励志成为糕手4 分钟前
深入剖析Spring IOC容器——原理、源码与实践全解析
java·开发语言·spring
Hello.Reader12 分钟前
Rust → WebAssembly 的性能剖析全指南
前端·rust·wasm
前端小巷子16 分钟前
Vue 2 Diff 算法
前端·vue.js·面试
杨DaB2 小时前
【SpringMVC】拦截器,实现小型登录验证
java·开发语言·后端·servlet·mvc
自由鬼3 小时前
如何处理Y2K38问题
java·运维·服务器·程序人生·安全·操作系统
敲上瘾3 小时前
渗透测试常用指令
服务器·测试工具·网络安全·压力测试
奕辰杰4 小时前
关于npm前端项目编译时栈溢出 Maximum call stack size exceeded的处理方案
前端·npm·node.js
北极糊的狐5 小时前
“我们无法设置移动热点”、网卡异常、电脑网络适配器没有2.4GHz 802.11n信道宽度和5.2GHz 802.11n信道宽度
运维·服务器
JiaLin_Denny6 小时前
如何在NPM上发布自己的React组件(包)
前端·react.js·npm·npm包·npm发布组件·npm发布包
路光.7 小时前
触发事件,按钮loading状态,封装hooks
前端·typescript·vue3hooks