前言:作者最近开始学习操作系统的相关知识啦!他很想把自己的笔记和理解分享给大家,如果你也正在从零开始学习操作系统,不妨继续看下去,希望这些内容会对你有帮助哦!
第四章:抽象:进程
导言:人们常常希望同时运行多个程序,一个正常的系统可能会有上百个进程同时运行,但事实上我们只有少量的物理CPU可用,因此我们的操作系统做的事情就是制造出几乎有无数个CPU可用的假象。
操作系统这种制造假象的方法叫做虚拟化CPU。其方式就是让一个进程只运行一个时间片,然后切换到其他进程,这就是时分共享(time sharing)CPU技术。
它能够允许用户运行多个并发进程,但潜在的开销就是性能损失,也就是说每个进程的运行都会变慢一点。
如果你想实现这种CPU的虚拟化,操作系统需要一些低级机制和一些高级智能。我们将低级机制称为机制。在这些机制之上,操作系统有一些智能以策略(policy)的形式存在。策略是在操作系统内做出某种决定的算法。这样的决定又是由操作系统中的调度策略(scheduling policy)来作出的。
4.1 抽象:进程
首先我们来聊聊什么是进程。
一句话:进程就是正在运行的程序的抽象。
说的具体一点:我们的程序原本都是一些死的二进制的文件,而操作系统做的事情就是将它们变成活的、可管理的、独立的东西,它们这些文件现在的状态就叫做进程。
一个进程需要跑起来,书中提到必须有以下三件东西,我们将它们统称为机器状态(machine state):
第一是内存(地址空间):代码、数据、栈和堆都放在哪
第二是寄存器:PC、栈指针、通用寄存器
第三就是I/O相关:比如说打开的文件
总的来说,进程就是程序 + 他当前所有的运行状态
现在你对于进程是什么,应该有了一个大概的了解?
4.2 进程API
现在我们已经知道了进程是什么,接下来我想知道,如果我想对进程做些什么,我该怎么办?
我们可以调用API接口,它是操作系统操作进程的方式,书中介绍了一些比较基本的操作:
创建(create)进程、销毁(destroy)进程、等待(wait)进程、其他控制、状态(state)
当然,这部分在这一章只是简略地介绍了一下哈哈,详细内容会在后续章节讲解
4.3进程创建:更多细节
这一部分我们将对上一节提到的“创建进程”这一操作做一些细节补充。
就是究竟我们的操作系统是怎么将一个程序变成进程的?其实核心就三件事:
1)把程序加载到内存
把磁盘上的代码和数据读到内存里;给进程分配栈、堆
Ps:栈是用来存放函数里的临时变量和记录函数调用关系的,而堆是用来动态申请内存的(比如说要建立链表或者像对数组扩容的时候会用到)
2)做各种初始化
打开标准文件:stdin、stdout、stderr;给进程一个 PID(身份证号)
3)让 CPU 开始跑程序
从 main函数开始执行;进程正式进入Running
这三个步骤概括一下,就是进程创建 = 加载程序 + 初始化 + 开始运行
除此之外,书里重点还讲了一个关键细节:
程序加载不是一次性全读完,而是:用到哪块,OS 再惰性(lazily)加载哪块(后面虚拟内存会细讲,这章只要知道有这回事就行)
4.4 进程状态
现在我们的进程创建完了,我们想知道它会有些什么状态
事实上,一个进程,一共就三种状态:
1)Running(运行)
正在 CPU 上执行指令,真在干活
2)Ready(就绪)
能跑,但别人在占CPU,等着 OS 叫它上场
3)Blocked(阻塞)
在等 I/O:等键盘、等磁盘、等网络;暂时不能跑,I/O 完了才会变回 Ready
它们之间怎么变?请看图示:

只是光嘴上这么说你可能没办法特别理解,接下来我们举一个例子:
首先我们说说什么叫做运行态,就是程序真的在CPU上跑,你可以右键任务栏打开任务管理器,同时打开wps文字开始打字,此时你正在运用wps写文档,那么wps这个程序就是running态,简单的来说,你现在在用哪个程序干活,哪个程序就是running态
接下来我们说一下就绪态,比如说你的文档写了一半,需要查资料,于是你打开浏览器开始查资料,但是你并没有关闭wps这个软件,你在用浏览器查资料的时候,wps就是就绪态。这个程序是一个准备好的状态,就等着你用,我们就叫他ready态。
最后我们说说阻塞态,就比如说你的文档写完之后保存好了,若干天后你又要打开这个文件。你打开它的时候,计算机需要读取硬盘,你在这个等待的过程中就是blocked态,读完之后加载好了就又变回ready态了
怎么样,是不是非常的清晰?非常的高手?
4.5 数据结构
刚才我们说到了每个进程的状态,事实上在实际运行时会有相当多的进程,那么操作系统为了记住每个进程的情况,要给每个进程建一个类似于档案一样的东西,我们给它取一个名字就叫做PCB(process control block)
里面记录了很多东西,比如说像什么这个进程它的PID、现在的状态、它的内存在哪里、寄存器的值、打开了哪些文件、优先级、账号、时间等等,我们的OS只有靠它才能管理所有进程
OS管理这些进程的方式就是将这些所有的PCB放在一起,组成链表或者队列,例如将所有Ready进程排在一起,就构成就绪队列,将所有Blocked进程排在一起就组成了阻塞队列。当我们的CPU空出来的时候就会从就绪队列里面拿一个出来跑
总结
到这里,《操作系统导论》第四章《抽象:进程》的核心内容就差不多梳理完了。我们从为什么要虚拟化 CPU开始,搞懂了进程到底是什么,跟着一步步看了进程 API、创建细节、三种状态切换,以及操作系统靠 PCB 怎么管理进程。
可以说,进程是操作系统最基础、最重要的抽象之一,后面的线程、调度、同步、虚拟内存等内容,几乎都是在这一章的基础上展开的。先把进程是什么、怎么跑、怎么管吃透,再去看后面的调度算法和实现细节,就会顺畅很多。
如果你也在啃操作系统,不妨先对着这一章的知识点,自己画一遍进程状态转换图,再想想:我们平时打开、切换、关闭软件时,操作系统到底在背后做了哪几步?把这些想明白,操作系统的大门就算真正迈进来了。



