共计 1327 个字符,预计需要花费 4 分钟才能阅读完成。
进程
为什么要引入进程?
从三个方面:资源分配,执行调度,错误隔离
一个目的:抽象程序的动态运行过程。
- 资源分配:为程序申请内存(存储程序代码 以及 用户输入的临时数据),申请 CPU 时间片(让它能执行)指定 IO 设备(让它能接受 IO 设备 的控制),这个进程还具有 唯一的标识,需求清单等信息,使得 OS 能够为该程序进行资源分配
- 执行调度:cpu 在 同一时间只能执行一个指令流(多核 cpu 抽象成单核来理解),但 cpu 为了实现“多任务并发执行”例如 边聊微信 边写文档,这需要让 cpu 在多个程序之间进行切换,每个进程,都拥有自己的 PCB(进程控制块),当需要切换任务时,比如在等待微信时我要写文档,cpu 会保存当前进程的 PCB 信息(比如当前运行到多少行代码了,寄存器的值是多少 下一条指令地址是?),然后再加载另一个进程的 PCB 信息,就能让 CPU 无缝衔接切换到另一个任务。目的在于(提高执行效率、CPU 利用率、提高系统的吞吐量)
- 错误隔离:如果让程序在 OS 中裸奔执行,多个程序共享一块内存空间——比如 A 程序的代码写错了,不小心修改了 B 程序的内存数据,会导致 B 程序崩溃;更严重的是,如果一个程序出现死循环(比如无限占用 CPU),会导致其他所有程序无法运行,甚至系统死机。但是进程有独立的地址空间((OS 给每个进程划分一块专属内存,进程只能访问自己的内存,不能直接修改其他进程的内存))比如微信崩溃,只会影响微信自己,不会影响其他程序的正常运行,如果没有进程隔离,一个错误程序就会导致整个 OS 崩溃(这是 OS 绝不允许的)
- 抽象进程的动态运行过程,程序段是静态的,运行程序时,OS 无法获知其运行状态。OS 需要管理这个程序的整个生命周期。比如 程序加载到内存中后 标记为“就绪”,执行中遇到 IO 操作 要标记为“阻塞”,进程刚好对应了这个动态过程:进程有完整的生命周期状态(就绪→运行→阻塞→终止),OS 通过管理进程的状态变化,就能实现对程序运行过程的管控。
总结:
简单来说:程序是“要做的事”,进程是“要做事的人 + 工具包”OS 不会让”事”自己去做,而是要让“带着工具包的人去做事”
进程的几种状态
- 就绪 当创建进程完毕 并完成必要的准备时,如申请 PCB,将程序和相关必要数据存入内存完成后,若这些步骤出错导致无法准备完毕,大部分是内存不足时,进程会进入静止就绪状态(此进程将不会被调度 转而保存在外存中)
- 执行 进程在就绪阶段 并分配了 cpu 进入执行过程
- 阻塞 正在运行的进程,由于发生某些事件(如 IO 请求,申请缓冲区失败)无法继续执行,此时会引发进程调度,os 会将处理机分配给另一个就绪进程
- 挂起 / 激活 这个状态的引入有一些场景存在的原因,这个状态下 进程是暂停的,正在执行则会进入暂停,若是就绪状态,则成为静止就绪 若是阻塞状态则成为静止阻塞
- 终端用户的需要
- 父进程的需要
- 负荷调节的需要
- OS 的需要
总结一下进程的一般状态流程:
null -> 创建:一个新进程的产生,这个进程处于创建状态
创建 -> 活动就绪:当系统性能和资源允许时,且完成必要的进程创建操作后,os 会将进程状态更换为活动就绪
创建 -> 静止就绪: 同上, 若不允许时, 则会进入静止就绪状态
执行 -> 终止: 执行完毕或者遇到无法客服的错误, 或是被 OS 以及其他进程所终止时, 会进入终止状态
未完待续!
正文完
文章二维码