操作系统笔记(王道考研) 第二章:进程管理(1)

大部分内容基于中国大学MOOC的2021考研数据结构课程所做的笔记,后续又根据2023年考研的大纲增加了一些内容,主要有操作系统引导、虚拟机、多级队列调度算法、互斥锁、调度器和闲逛进程、内存映射文件、文件系统的全局结构、虚拟文件系统、固态硬盘SSD、输入输出应用程序接口 、驱动程序接口等等。

感谢我的室友HXN,他帮我写了一部分第五章的内容。

课程内容和西电平时讲课的内容大致重合,西电可能每章会多讲一点UNIX系统的实例,可以听完这课再快速过一遍老师的课件防止漏掉什么内容。

这门课讲的其实不算特别硬核,没怎么涉及具体的代码。不过我其实感觉操作系统是个大无底洞,能学到多深基本取决于愿意花多少时间和精力。如果有闲心,推荐看下南大蒋炎岩老师的《操作系统:设计与实现》和哈工大李治军老师的《操作系统》,讲的更深入,当然难度也相应的大的多。

 

其他各章节的链接如下:

操作系统笔记(王道考研) 第一章:计算机系统概述

操作系统笔记(王道考研) 第二章:进程管理(1)

操作系统笔记(王道考研) 第二章:进程管理(2)

操作系统笔记(王道考研) 第三章:内存管理

操作系统笔记(王道考研) 第四章:文件管理

操作系统笔记(王道考研) 第五章:输入输出(I/O)管理

其他各科笔记汇总

进程管理

进程的概念和特征

image-20210309102351703

在引入了线程之后,进程就不再是接受调度的基本单位了

进程的概念

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ljB2NIzg-1660639602514)(https://xdu-cslee-blog.oss-cn-hangzhou.aliyuncs.com/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/image-20210309102558789-16606376408461.png)]

虽然这些进程的名称都差不多,但是它们背后都有各自的PID

进程的组成 —— PCB

操作系统在背后不只是记录了各个进程的PI,除了PID之外,它还记录了各个进程的其他一些信息

image-20210309102849105

使用苹果电脑的活动监视器小工具(和Windows的任务管理器类似)来看现在系统上正在运行的进程。可以发现我们每一次新建一个进程,都会给它分配一个不重复的,唯一的PID。而且在很多操作系统中,PID的分配都是每一次加1这样很简单的策略
在这里插入图片描述

image-20210309104059664

课程里以Linux的内核原码为例,在sched.h文件当中查看Linux操作系统当中定义的PCB长什么样子(名字叫task_struct)。
在这里插入图片描述

进程的组成 —— 程序段 ,数据段

image-20210309104603955

具体看一个例子来理解这句话

程序是如何运行的?

image-20210309104750595

image-20210309104811159

可执行文件平时存放在硬盘当中,这个文件当中保存的就是我们上面说的一系列指令序列

除了PCB之外,这个程序的一系列指令序列也需要读到内存当中,这一系列的指令序列我们称之为程序段。此外变量的内容也需要被放在内存中,所以还会有数据段用来存放中间数据

进程的组成

image-20210309110028013

 

进程的状态,进程的组织

image-20210309110321692

进程状态的转换

image-20210309111520550

什么叫时间片用完见第一章的时钟中断

进程正在被创建时,它的状态是“创建态”,在这个阶段操作系统会为进程分配资源、初始化PCB

当进程创建完成后,便进入“就绪态”,处于就绪态的进程已经具备运行条件,但由于没有空闲CPU就暂时不能运行

系统中可能会有很多个进程都处于就绪态,当CPU空闲时,操作系统就会选择一个就绪进程,让它上处理机(CPU)运行。如果一个进程此时在CPU上运行,那么这个进程处于“运行态”。CPU会执行该进程对应的程序(执行指令序列)

在进程运行的过程中,可能会请求等待某个事件的发生(如等待某种系统资源的分配,或者等待其他进程的响应)。在这个事件发生之前,进程无法继续往下执行,此时操作系统会让这个进程下CPU,并让它进入“阻塞态”
当CPU空闲时,又会选择另一个“就绪态”进程上CPU运行。当等待的事件发生时,进程从“阻塞态”回到“就绪态”

一个进程可以执行 exit 系统调用,请求操作系统终止该进程。此时该进程会进入“终止态”,操作系统会让该进程下CPU,并回收内存空间等资源,最后还要回收该进程的PCB。当终止进程的工作完成之后,这个进程就彻底消失了

举了打印机的例子,此处略过不计

进程的状态

image-20210309111556053

进程的组织

image-20210309112945350

链接方式

image-20210309111706917
在这里插入图片描述

比如等待打印机的阻塞队列和等待磁盘的阻塞队列

 

索引方式

image-20210309112912090

 

进程控制

image-20210309114131810

什么是进程控制?

image-20210309113656282

创建新进程:让一个进程从无到有,从创建态到就绪态

撤销已有进程:让进程进入终止态,最终消灭进程

如何实现进程控制?

image-20210309115351593

image-20210316143652154

如何实现原语的”原子性“?

image-20210316144841374

image-20210316144906035

如果这两个特权指令允许普通的用户程序使用的话,就意味着可以在程序的开头就植入一个关中断指令,然后一直到程序的末尾再执行开中断指令。这样的话只要该程序上CPU运行了就肯定会一直霸占着CPU而不会被中断,显然这种情况是不应该让它发生的

进程控制相关的原语

image-20210316151225759

作业:此时还放在外存里的那些还没有投入运行的程序

作业调度:从外存中挑选一个程序把它放入内存然后开始运行

image-20210316151805004

在这里插入图片描述
上图显示了此时电脑当中正在运行的各种进程,该界面的显示方式反映了进程间的父子进程
launchd是装入进程,开机后启动的所有别的进程都是launchd的子进程

image-20210316194343175

image-20210316194930026

下面来探讨一下什么叫保存运行环境和恢复运行环境,这是实现进程并发执行的一个很关键的技术

知识滚雪球:程序是如何运行的?

这段计算机组织与体系结构里会讲,此处过程基本略过不计

所谓的运行环境就是进程在运行过程当中寄存器里存储的那些中间结果

另一个进程在上CPU运行的时候有可能会把前一个进程在寄存器中保留的中间结果覆盖掉。为了解决这个问题,可以采取这样的策略:当一个进程要下处理机的时候可以把它之前运行环境的一些必要的信息保存在自己的PCB当中再切换成别的进程。当之前的进程重新回到CPU运行的时候,操作系统就可以根据之前保存下来的这些信息来恢复它的运行环境

 

进程通信

在这里插入图片描述

什么是进程通信?

在这里插入图片描述

为什么进程通信需要操作系统支持?

在这里插入图片描述

共享存储

在这里插入图片描述

在Linux中实现共享存储
比如进程P和Q想要通信,发起通信的进程P通过shm_open系统调用申请一片共享内存区,接下来进程P和Q都需要通过mmap系统调用把共享内存区映射到自己的虚拟地址空间
调用mmap函数后,进程的页表项/段表项会增加一项,这个页面/段就可以映射到刚才申请的共享内存区

在这里插入图片描述

消息传递

在这里插入图片描述

消息传递(直接通信方式)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

各个进程的PCB当中包含一个消息队列

进程P要给Q发送消息msg,首先要在自己的地址空间完善msg信息。然后使用操作系统提供的发送原语send指明msg要发送给Q,该原语会导致操作系统内核接收到msg并将其挂到在进程Q的消息队列里面。进程Q使用接收原语receive指明要接收P发来的msg,操作系统检查Q的消息队列并把msg复制到Q的地址空间

消息传递(间接通信方式)

进程P和Q之间要通信,P通过系统调用向操作系统申请一个或多个信箱


在这里插入图片描述
在这里插入图片描述

管道通信

在这里插入图片描述
在这里插入图片描述

这个缓冲区的大小一般和内存页面是一样的,像Linux系统当中一个管道对应的缓冲区的大小就是4KB

早期的System V操作系统采用第一种解决方案

 

线程的概念

image-20210316205711855

什么是线程,为什么要引入线程?

还没引入进程之前,系统中各个程序只能串行执行,做不到边聊QQ边听音乐,而引入了进程之后就能做到了。QQ能同时做到文字聊天,视频聊天和传送文件,但在传统的进程定义当中进程是程序的一次执行,这些功能显然不可能是由一个程序顺序处理就能实现的,因此引入线程。

引入了线程之后,CPU的服务对象就不再是进程,而是进程当中的线程,每一个进程当中可能会包含多个线程,然后CPU会用一定的算法轮流地为这些线程进行服务

image-20210316211342270

image-20210316211701946

引入线程机制后,有什么变化?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YAS5Y8Gv-1660639602550)(https://xdu-cslee-blog.oss-cn-hangzhou.aliyuncs.com/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/image-20210316211808695-16606376408482.png)]

线程的属性

image-20210316212936827

系统资源分配是分配给进程的,所以线程几乎不拥有系统资源

 

多线程模型

image-20210316213916656

线程的实现方式

image-20210319084930980

在这个时代操作系统的视角看到的其实依然是只有进程,但是程序员们写的这些应用程序当中可以使用线程库来实现多个线程并发地运行

image-20210319084951463

在上例中,操作系统其实只看得到进程,而这个进程上处理机运行的时候其实是程序员自己写了一个线程库来创建了逻辑上的线程,也就是所谓的用户级线程,那我们来思考这样几个问题

image-20210319085414595

image-20210319085438114

上面写的while循环其实就是简单地实现了对这三个线程的管理,让它们交替地运行,所以用户级线程的管理并不是操作系统负责的

上例中线程切换是由while循环来控制的,这并不需要涉及请求操作系统服务之类的事情,所以线程切换的管理是由线程库,应用程序自己完成的

操作系统只能看到进程的存在,它只知道这个进程是一堆代码,而在这堆代码里又分别被分为了几个线程

用户级线程的管理工作,包括切换创建等待,这些工作都不需要请求操作系统的服务,只需要在用户态下就可以完成

从上例的伪代码来理解用户级线程并发度不高的缺点

另外虽然上一小节中提到过引入线程后线程成了CPU调度的基本单位,但是如果这个线程是用用户级线程来实现的,CPU的调度单位依然是进程,操作系统是给进程分配CPU时间的。因此即便我们的电脑是多核处理机,但是由于进程才是CPU调度的基本单位,因此这个进程只能被分配一个核心,所以这些线程并不能并行地运行

image-20210319092055962

image-20210319092133068

如果某一个操作系统支持内核级线程的话,在这种操作系统当中,内核级线程是处理机调度的基本单位,而进程只作为分配资源的基本单位,因此在多核CPU的环境下这几个线程可以分别分派到不同的核心下并行地执行

 

在支持内核级线程的系统当中如果再引入线程库的话就可以实现把若干个用户级线程映射到某一个内核级线程。根据用户级线程和内核级线程的映射关系就引出了三种多线程模型

多线程模型

image-20210319093337242

image-20210319093412864

image-20210319093440093

 

线程的状态与转换

线程的状态与转换

在这里插入图片描述

线程的组织与控制

在这里插入图片描述

调度的概念,层次

image-20210319094315041

调度的基本概念

image-20210319104246179

调度的三个层次 —— 高级调度

image-20210319120105001

调度的三个层次 —— 低级调度

image-20210319120219556

调度的三个层次 —— 中级调度

image-20210319120312340

切换程序或者说切换进程的时候可能有时很快,有时很慢。有一种可能的原因就是当你的进程切换的很快的时候,这个进程的数据有可能是放在内存里面的,而切换进程很卡很慢的时候有可能是因为那个进程的数据之前已经不在内存里了,而是被系统调到了外存当中,所以当你切换进程的时候系统发现这个进程现在非运行不可,它会临时地把这个进程相关的数据从外存再读回内存,这样之后这个进程才可以顺利地运行,因此你会感受到一丝卡顿,其实卡顿的过程就是系统在进行中级调度

补充知识:进程的挂起态与七状态模型

在这里插入图片描述

三层调度的联系、对比

image-20210319120507632

 

进程调度的时机,切换与进程,进程调度方式

image-20210319141555133

进程调度的时机

image-20210319151706648

image-20210319155419477

各个进程只能互斥地进入临界区,互斥地执行这段访问临界资源的代码

当一个进程此时处于内核程序临界区,并且这个临界区它是要访问就绪队列的话,那么在访问之前它会把这个就绪队列上锁。如果这个进程当前还没有退出内核程序临界区,就意味着这个临界资源没有被解锁。那么在没有解锁的过程中如果说我们要发生进程调度的话,进程调度相关的程序肯定是需要访问就绪队列这个临界资源的,因为它要从就绪队列当中挑选一个进程为它分配处理机。由于就绪队列这个临界资源此时还是上锁的状态,所以说如果在这种状态下去进行进程调度的话,这个进程调度肯定是没办法顺利地进行下去的,因为此时还没有解锁

所以可以看到对于内核程序临界区访问的这些临界资源,也就是这些内核数据结构而言,如果这些内核数据结构,这些临界资源被上锁了并且没有被尽快地释放的话,那么有可能会影响到操作系统内核其他的管理工作,比如说刚才聊到的进程切换。所以说我们在访问这些内核程序临界区期间不能进行进程的调度与切换。我们必须让进程尽快地执行完内核程序临界区的那些代码,然后完成对这个临界资源的访问,再尽快地把对临界资源的锁给解除,只有这样其他的操作系统内核才可以继续有序地进行管理工作

而另外一种情况,假如此时进程访问的是一种普通的临界资源,比如说是一个打印机的话,那么进程在访问它的时候会先进行上锁。打印机在打印完成之前,这个进程是一直在临界区内的,它还一直保持着对打印机的访问。由于它还没有退出临界区,所以这个临界资源并不会被解锁,但是打印机又是一种慢速的I/O设备,如果这个情况下不允许进程调度,进程切换的话就会导致这个进程它需要一直空等着打印机打印结束,在这个进程空等的过程当中它同时还霸占着CPU,所以CPU可以说处于空闲状态。所以如果说这个进程在访问一个普通的临界资源,在一个普通的临界区当中的话,这个情况下其实是应该进行进程调度的

因为普通临界区访问的这些普通的临界资源并不会像之前一样直接地影响到操作系统内核的管理工作。所以说为了增加系统的并发度,增加CPU的利用率,在访问这些普通的临界区的时候是可以进行进程调度和切换的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RDVmXTpN-1660639602571)(https://xdu-cslee-blog.oss-cn-hangzhou.aliyuncs.com/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/image-20210319155525807-16606376408494.png)]

由当前运行的进程是否可以被强行地剥夺处理机资源引出下一个知识点

进程调度的方式

image-20210319155738340

image-20210319155752220

对数据进行保存其实是保存到了PCB当中,而对这些数据进行恢复其实是从PCB当中读出这些数据并且把这些数据放到相应的寄存器当中

不能简单地认为进程切换越频繁进程的并发度就越高

 

调度器与闲逛进程

调度器/调度程序(scheduler)

在这里插入图片描述

在这里插入图片描述

闲逛进程

在这里插入图片描述

调度算法的评价指标

image-20210319162512725

CPU 利用率

image-20210319162624815

系统吞吐量

image-20210319162712914

周转时间

image-20210319162816432

后面的这三项就是就绪态,运行态和阻塞态。这三项在整个作业的处理过程当中是会发生多次的,整个过程中只会有一次作业调度

image-20210319162902024

等待时间

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZBPfXklK-1660639602581)(https://xdu-cslee-blog.oss-cn-hangzhou.aliyuncs.com/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/image-20210319162925505-16606376408493.png)]

响应时间

image-20210319162941018

 

FCFS,SJF,HRRN调度算法

image-20210319163109272

先来先服务(FCFS,First Come First Serve)

image-20210319200237095

先到达就绪队列或者先到达后备队列的作业/进程就先为它服务

后备队列在外存中,就绪队列在内存中

对于当前正在占用处理机的进程/作业,只有进程主动放弃处理机的时候才会进行调度,才会用调度算法的规则来选择下一个应该得到服务的进程

image-20210319202316565

注意给出的进程都是纯计算型的进程,也就是说这些进程只需要CPU为它们服务

image-20210319203209689

短作业优先(SJF, Shortest Job First)

从刚才这个例子可以知道FCFS算法对于带权周转时间还有平均等待时间这些指标其实是不太优秀的

image-20210319203532126

image-20210319204120779

image-20210319204203481

image-20210319210527634

image-20210319210713211

image-20210319210734249

对 FCFS 和 SJF 两种算法的思考

image-20210319210826693

高响应比优先(HRRN, Highest Response Ratio Next)

image-20210319210930901

image-20210319211006585

这个题目当中由于它是纯计算型的一些进程所以并不会有I/O操作,也就是并不会主动地要求阻塞

image-20210319211026895

时间片轮转,优先级,多级反馈队列调度算法

image-20210319212115505

非抢占式的优先级调度算法只需要注意各个进程主动地放弃处理机的时刻,我们在这个时刻检查是否需要调度就可以了。而对于抢占式的优先级调度算法来说,除了刚才所说的情况之外还需要注意就绪队列发生改变的这种情况下是否会发生抢占,在这个时候也需要进行检查

时间片轮转(RR, Round-Robin)

时间片轮转调度算法是伴随着分时操作系统的诞生而诞生的

image-20210319212238912

image-20210319223141573

请无视这几张图片中对于就绪队列的图片描述

image-20210319223324386

image-20210319223419977

image-20210319223527283

image-20210319223632136

假如说我们按照先来先服务调度算法来调度这些程序/进程的话,它的调度顺序和时间片为5的情况是很类似的。除了多了个地方操作系统还需要做一个小小的检查之外,其他的这些发生调度的时机,还有调度的顺序都是一模一样的

如果时间片太大,使得每个进程都可以在一个时间片内就完成,则时间片轮转调度算法退化为先来先服务调度算法,并且会增大进程响应时间。因此时间片不能太大

另一方面,进程调度,切换是有时间代价的(保存,恢复运行环境),因此如果时间片太小,会导致进程切换过于频繁,系统会花大量的时间来处理进程切换,从而导致实际用于进程执行的时间比例减少。可见时间片也不能太小

image-20210319223758317

优先级调度算法

image-20210320142629521

image-20210320142650701

image-20210320142710280

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c7tAilai-1660639602610)(https://xdu-cslee-blog.oss-cn-hangzhou.aliyuncs.com/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0%E5%9B%BE%E7%89%87/image-20210320142729362-16606376408495.png)]

因为前台进程毕竟是现在用户能看到的进程,所以这些进程的流畅程度之类的指标肯定比后台进程更重要,它的优先级也理应要高于后台进程。在iPhone和Android这些手机上就有这样一个原则

image-20210320143946128

思考

image-20210320144016582

多级反馈队列调度算法

image-20210320145742804

请无视下面的例题中对算法执行过程的图片描述

image-20210320145802582

image-20210320145817046

如果源源不断地有短进程到达的话,那么可能短进程在第一级队列被分配一个较短的时间片之后就可以被处理完。如果这种进程源源不断地到来的话,已经被降级为更低优先级的那些进程就有可能长期得不到服务,从而导致饥饿的现象

多级队列调度算法

在这里插入图片描述

  • 9
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值