Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

进程控制块与进程状态

复习

  • 系统调用:用户程序怎样安全地请求内核服务
  • 程序如何变成进程:区分静态的程序文件和运行中的进程
  • 进程的创建与结束:父子进程、退出状态和资源回收

TL;DR

  • 内核用进程控制块(PCB) 记录一个进程的全部信息
  • PCB 里有身份、运行现场、占用资源和当前状态
  • 进程有三种基本状态:运行、就绪、阻塞
  • 状态随事件彼此转换,内核据此决定让谁上 CPU

正文

  内核同时管着成百上千个进程。它总得有个地方,把每个进程的情况记下来。这个“档案”,就是进程控制块(PCB,Process Control Block)。

一份进程档案

  PCB 是内核为每个进程维护的数据结构。前面几章零零散散提到的信息,最后都收在这里:

  • 身份:进程编号,父子是谁
  • 运行现场:PC 值、各寄存器的内容、栈的位置
  • 资源:占用了哪些内存、打开了哪些文件
  • 状态:它是正在跑,还是闲着,还是在等
  • 调度信息:优先级等,供内核决定谁先上 CPU

  可以说,PCB 就是进程在操作系统里的“户口本”。找到 PCB,就等于找到了这个进程的一切。

三种基本状态

  一个进程,随时处在下列三种基本状态之一:

  • 运行(Running):正占用 CPU,在跑
  • 就绪(Ready):一切都准备好了,只差一个 CPU
  • 阻塞(Blocking):在等某个事件发生,就算给它 CPU 也没用

  “就绪”和“阻塞”最容易混。区别在于:

  • 就绪,是缺 CPU
  • 阻塞,是缺事件(比如等磁盘读完、等用户按键)

状态怎么变

  状态不是固定的,它会随事件来回转换:

        ┌──────────── 被调度 ────────────┐
        ▼                                │
    ┌───────┐   时间片用完    ┌───────┐   │
    │ 就绪  │ ───────────────>│ 运行  │───┘
    └───────┘ <───────────────└───────┘
        ▲        事件完成         │ 等待事件
        │                         ▼
        │                   ┌───────┐
        └───────────────────│ 阻塞  │
                            └───────┘
  • 就绪 → 运行:内核选中了它,把 CPU 交给它
  • 运行 → 就绪:时间片用完(不能让一个进程一直霸着 CPU)
  • 运行 → 阻塞:它要等一件事,比如发起了一次磁盘读取
  • 阻塞 → 就绪:它等的事情完成了,重新排队等 CPU

  顺带一提:阻塞的进程不会“占着 CPU 空等”。它一进入阻塞,内核就把 CPU 让给别的就绪进程,自己去等事件——这正是不让 CPU 浪费的关键。

队列

  把同状态的进程排到一起,管理起来就方便了:所有就绪的进程排成就绪队列,谁被调度就看这个队列;等待不同事件的进程,分别排在各自的阻塞队列里。

  于是内核的调度工作,很大程度上就是:在就绪队列里挑一个,运行它;它一旦让出 CPU,再挑下一个。

  既然多个就绪进程要轮流上 CPU,那“换人”这件事就必须做利索。下一章,我们看内核怎样干净地把 CPU 从一个进程交给另一个——上下文切换

思考题

  一个进程发起磁盘读取后进入阻塞,另一个进程还在就绪队列里等着。如果内核不把前者的状态从“运行”改成“阻塞”,会发生什么?为什么“就绪”和“阻塞”必须分开?

小结

知识点

  • PCB 记录进程的身份、现场、资源与状态
  • 三种基本状态:运行、就绪、阻塞
  • 就绪缺 CPU,阻塞缺事件
  • 状态随调度与事件相互转换
  • 同状态的进程排成队列,便于管理

参考资料

  1. Wikipedia(zh):进程控制块:PCB
  2. Wikipedia(zh):进程状态:运行、就绪与阻塞

思考题答案(仅供参考)

  如果不把它改成阻塞,内核会以为它还能继续跑,于是反复把它调度上 CPU;可它实际在等磁盘,上 CPU 也只会再次发现“还没好”,白白浪费 CPU 时间。把“就绪”和“阻塞”分开,内核才能一眼看出:哪些进程给了 CPU 就能干活,哪些进程给了也是白给。这样才能把 CPU 只分给真正能用它的进程,避免空转。

协议

  本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

封面图

设计师 | 南国微雪