本系列文章为408考研操作系统知识点整理仅涉及到一些重要的考研知识点并不是完全系统全面的知识,参考书目和视频资料:汤小丹 计算机操作系统(第四版),操作系统考研复习指导,B站王道考研操作系统视频课。

2.1.1 进程的概念与特征

程序:这是一个静态概念,本质是存放在磁盘中的可执行文件,也即一系列指令的集合。它告诉进程在执行时应该做哪些事情,也即完成怎样的功能
进程:这是一个动态概念,是程序的一次执行过程,有了进程程序所描述的功能才可能得以实现
总之:没有程序,进程将无事可做;而没有进程,程序将无法完成:并且同一个程序多次执行会对应多个进程

PCB

进程控制块(PCB):如前面所述,进程就像一张“综合测评表”,记录着程序的一切信息。在操作系统中,这张“综合测评表'我们称其为进程控制块(PCB),它的本质就是一个数据结构,也就是说每个进程对应一个PCB,PCB是进程存在的唯一标识。这样一来,操作系统就把对进程这种抽象概念的管理转化为了对PCB这种数据结构的管理
创建进程就等价于创建数据结构PCB;撤销进程就等价于释放数据结构PCB
注意:PCB是进程控制块的英文简写,但不同操作系统在实现其PCB时名字往往不同。

具体来说,PCB中会存放如下信息
进程标识符:用于标识各个进程,每个进程都有唯一一个标识号
进程控制和管理信息:例如当前进程的状态、进程的优先级等
资源分配清单:用于说明有关内存地址空间或虚拟地址空间的状况、所打开文件的列表和所使用的输入输入设备信息
处理机相关信息:主要指处理机中各寄存器的值

进程的组成

进程的组成:一个进程由PCB、程序段和数据段这三部分组成。其中PCB是给操作系统用的,而程序段和数据段则是给进程自己使用的
PCB : 操作系统对进程进行管理工作所需的信息都存在PCB中
程序段:包含程序指令
数据段:包含程序运行时产生的各种数据

进程:引入程序段、数据段和PCB后,进程可以被定义为——进程是进程实体的运行过程,是系统进行资源分配和调度的独立单位

进程的组织

在一个系统中,通常存在着许多进程的PCB,有的处于就绪态,有的处于阻塞态,而且阻塞的原因各不相同。为了方便进程的调度和管理,需要将各进程的PCB用适当的方法组织起来。目前,常用的组织方式有链接方式和索引方式两种。链接方式将同一状态的PCB链接成一个队列,不同状态对应不同的队列,也可把处于阻塞态的进程的PCB,根据其阻塞原因的不同,排成多个阻塞队列。索引方式将同一状态的进程组织在一个索引表中,索引表的表项指向相应的PCB,不同状态对应不同的索引表,如就绪索引表和阻塞索引表等。

进程的特征

进程具有如下特征
动态性:进程是程序的一次执行过程,是动态地产生、变化和消亡的,动态性是进程最基本的特征
并发性:内存中有多个进程实体,各进程可以并发执行
独立性进程能独立运行、独立获得资源、独立接受调度的基本单位
异步性:各进程按各自独立的、不可预知的速度向前推进,操作系统要提供“进程同步机制”来解决异步问题

2.1.2 进程的状态和转换

进程状态

进程状态:进程在其生命周期内,由于系统中各进程之间的相互制约关系及系统的运行环境的变化,所以进程的状态也在不断地发生着变化。通常进程会有以下五种状态,其中前三种是进程的基本状态
运行态:进程正在处理机上运行,占有CPU。单核处理机下,每一个时刻最多只能有一个进程处于运行态
就绪态:已经具备运行条件,但是由于没有空闲的CPU,从而暂时不能运行。系统中处于就绪状态的进程可能有多个,通常将他们排成一个队列,称为就绪队列
阻塞态/等待态:进程正在等待某一事件而暂停运行。比如等待某资源为“可用”或等待输入输出完成。处于该状态下,即使处理机空闲,该进程也不能投入运行
创建态:进程正在被创建,尚未被转到就绪态。创建进程时首先申请一个空白的PCB,并向PCB中填写一些控制和管理进程的信息,然后由系统为该进程分配运行时所必需的资源,最后把该进程转入到就绪态
结束态:进程正在从系统中消失,可能是进程正常结束或其他原因中断退出运行。进程需要结束运行时,系统置该进程为结束态,然后再进一步处理资源释放和回收等操作

进程状态转换

进程状态转换:
创建态:由系统完成创建进程的一系列工作,不出意外接下来会转到就绪态
就绪态->运行态:处于就绪态的进程被调度后,获得处理机资源,于是进程由就绪态转为运行态
运行态->就绪态:处于运行态的进程在时间片到之后,不得不让出处理机,从而进程由运行态转为就绪态。此外,在可剥夺的操作系统中,当有更高优先级的进程就绪时,优先级低的会被剥夺处理机的使用权(即使时间片未到),让更高优先级的进程运行
运行态->阻塞态:进程请求某一资源(比如外设)的使用和分配或等待某一事件的发生(比如IO操作的完成),这是一种特殊的、由运行用户态程序调用操作系统内核过程的形式
阻塞态>就绪态:进程等待的事件到来时(比如IO操作结束或中断结束),中断处理程序必须把相应进程的状态由阻塞态转为就绪态

注意:
运行态到阻塞态是一种进程自身做出的主动行为;阻塞态到就绪态不是进程自己可以控制的,是一种被动行为
阻塞态不能直接转为运行态,就绪态也不能直接转为阻塞态

2.1.3 进程控制

原语:按层次结构设计的操作系统,底层必然是一些可被调用的公用小程序,他们各自完成一个规定的操作,定义原语的直接方法是关闭中断,使所有动作不可分割地完成后再打开中断。

为什么使用原语?

进程控制(进程状态转换)是一个复杂的过程,整个过程需要一气呵成,也即不能中断,所以需要依靠原语来实现。想要实现进程的状态转换,操作系统至少需要2步:
1.修改PCB中的用于标识进程目前状态的变量state
2.将进程投递到对应的队列
以上的步骤中,如果在完成第1步后被中断了,那么就会产生矛盾:进程状态被改变了但却没有在对应的队列中

进程的创建

进程创建:一个进程创建另一个进程,此时创建者称为父进程,被创建的进程称之为子进程
子进程可以继承父进程所拥有的资源
子进程撤销时,应将其从父进程哪里获得的资源还给父进程
创建新进程的过程如下
1.申请空白PCB:为新进程分配一个唯一的进程标识号,并申请一个空白的PCB,若PCB申请失败,则进程创建失败
2.为新进程分配所需资源:为新进程的程序和数据及用户栈分配必要的内存空间,注意若资源不足,处于创建态等待资源
3.初始化PCB:主要包括初始化标志信息、初始化处理机状态信息和初始化处理机控制信息,以及设置进程的优先级等等
4.将PCB插入就绪队列:若进程就绪队列能够接纳新进程,则将新进程插入就绪队列,等待被调度运行

可以引起进程创建的事件有
用户登录:分时系统中,用户登录成功,系统会为其建立一个新的进程。
作业调度:多道批处理系统中,有新的作业放入内存时,会为其建立一个新的进程
提供服务:用户向操作系统提出某些请求时,会建立一个进程处理该请求
应用请求:由用户进程主动请求创建一个子进程。比如Linux中的系统调用fork

终止进程

操作系统终止进程的过程如下:
1.根据被终止进程的标识符,检索PCB,从中读出该进程的状态
2.若被终止进程处于执行状态,立即终止该进程的执行,将处理机资源分配给其他进程
3.若该进程还有子刊孙进程,则应将其所有子孙进程终止
4.将该进程所拥有的全部资源归还给操作系统或其父进程
5.将其PCB从所在队列中删除

引起进程终止的事件主要有:
正常结束:表示进程的任务已经完成并准备退出运行
异常结束:表示进程在运行时,发生了某种异常事件,使程序无法继续运行。比如存储区越界、保护错误、非法指令、特权指令错误、运行超时、浮点异常等等
外界干预:指进程相应外界的请求而终止运行。比如操作员或操作系统干预、父进程请求或父进程终止

进程阻塞和唤醒

进程阻塞执行过程如下
1.找到将要被阻塞进程的对应的PCB
2.若该进程为运行态,则需要保护其现场,然后将其状态转换为阻塞态,停止运行
3.把PCB插入相应事件的等待队列,将处理机资源调度给其他就绪进程
引起进程阻塞的事件有
需要等待系统分配某种资源
需要等待相互合作的其他进程完成工作

唤醒进程的执行过程如下
1.在该事件的等待队列中找到相应进程的PCB
2.将其从等待队列中移除,并置其状态为就绪态
3.把该PCB插入就绪队列,等待调度程序调度
注意:Block和Wakeup作用刚好相反,必须成对使用
Block:是由被阻塞进程自我调用实现的
Wakeup:是由一个与被唤醒进程合作或其他相关进程调用实现的

进程切换

进程切换的过程如下
1.保存处理机上下文,包括程序计数器和其他寄存器
2.更新PCB信息
3.把进程的PCB移入相应的队列,如就绪、阻塞等队列
4.选择另一个程序进程执行,并更新其PCB
5.更新内存管理的数据结构
6.恢复处理机上下文
引起进程切换的事件有:
当前进程时间片已到
更高优先级的进程到达
当前进程主动阻塞
当前进程终止

2.1.4 进程的通信

进程间通信(IPC):进程是操作系统分配资源的基本单位,每个进程拥有各自独立的地址空间,在正常情况下,它们是互不干扰的,体现了进程的独立性。PV操作是低级通信方式。高级通信方式主要有以下三种。

共享存储

共享存储:每个进程都有自己的地址空间(虚拟的),页表负责将虚拟内存映射到真实的物理内存处

既然页表是负责映射的,那么自然就可以在物理内存上开辟一片空间,然后让他们都映射到同一片内存空间,这样的话就可以进程间通信了。其中被映射的区域称其为共享存储区。

需要注意的是,为避免出错,各进程对共享空间的访问应该是互斥

共享存储分类:分为以下两类
基于数据结构的共享:这种共享方式速度慢、限制多,是一种低级通信方式
基于存储区的共享:是指操作系统在内存中会划分出一块共享存储区,数据的形式、存放位置都由通信进程控制,而不是操作系统,是一种高级通信方式

消息传递

消息传递:进程间的数据交换以格式化的消息(Message)为单位。进程通过操作系统提供的发送消息 接收消息两个原语进行数据交换
消息由以下两部分构成
消息头:包括发送进程DI、接受进程ID、消息长度等格式化信息
消息体:消息的主体内容

消息传递有以下两种方式
直接通信方式:消息的发送进程直接指明接受进程的ID
间接通信方式:通过“信箱”间接通信,所以又称为信息通信方式

管道

在Linux中,管道是一种使用非常频繁的通信机制。从本质上说,管道也是一种文件,但它又和一般的文件有所不同,管道可以克服使用文件进行通信的两个问题,具体表现如下:
1)限制管道的大小。管道文件是一个固定大小的缓冲区,在Liux中该缓冲区的大小为4KB,这使得它的大小不像普通文件那样不加检验地增长。使用单个固定缓冲区也会带来问题,比如在写管道时可能变满,这种情况发生时,随后对管道的write()调用将默认地被阻塞,等待某些数据被读取,以便腾出足够的空间供write()调用写。
2)读进程也可能工作得比写进程快。当所有管道内的数据已被读取时,管道变空。当这种情况发生时,一个随后的read()调用将默认地被阻塞,等待某些数据被写入,这解决了read()调用返回文件结束的问题。
管道只能由创建进程所访问,当父进程创建一个管道后,由于管道是一种特殊文件,子进程会继承父进程的打开文件,因此子进程也继承父进程的管道,并使用它来与父进程进进行通信。

注意:从管道读数据是一次性操作,数据一旦被读取,就释放空间以便写更多数据。普通管道只允许单向通信若要实现父子进程双向通信,则需要定义两个管道。

2.1.5 线程

线程:线程是进程的一个执行流,处在进程的地址空间内,进程和线程的关系是1 :n。引入线程后,进程是资源分配的基本单位,线程是调度的基本单位

资源分配和调度方面
引入线程前:进程是资源分配和调度的基本的单位
引入线程后:进程是资源分配的基本单位,线程是调度的基本单位
并发性方面:
引入线程前:只能进程间并发
引入线程后:线程间也可以并发,提高了并发度
系统开销:
引入线程前:进程切换开销很大
引入线程后:同一进程内的线程切换开销小

线程属性:

  • 线程是处理机调度的单位
  • 多CPU计算机中,各个线程可占用不同的CPU
  • 每个线程都有一个线程ID、线程控制块(TCB)
  • 线程也有就绪、阻塞、运行三种基本状态
  • 线程几乎不拥有系统资源
  • 同一进程的不同线程间共享进程的资源
  • 由于共享内存地址空间,同一进程中的线程间通信甚至无需系统干预
  • 同一进程中的线程切换,不会引起进程切换:不同进程中的线程切换,会引起进程切换
  • 切换同进程内的线程,系统开销很小
  • 切换进程,系统开销较大

线程共享进程数据,但是也有自己的一部分数据

  • 线程ID
  • 一组寄存器(硬件上下文)
  • errno
  • 信号屏蔽字
  • 调度优先级

进程的多个线程共享地址空间,因此文本段,数据段都是共享的,所以一个全局变量多个线程都可以访问。除此之外,以下资源也是共享的

  • 文件描述符表
  • 每种信号的处理方式
  • 当前工作目录
  • 用户ID和组ID

线程的组织与控制与进程的组织控制基本一致,也会有与之对应的数据结构,即线程控制块TCB

2.1.6 线程实现方式和多线程模型

线程实现方式

用户级线程(ULT):由应用程序通过线程库实现,所有的线程管理工作都由应用程序负责。用户认为是有多个线程的,但是操作系统根本就不理会,他认为线程是不存在的。操作系统在调度时只按照它的规则,它会按照进程调度,但在用户层,比如一些线程库它会把这些进程当作线程处理
线程的管理工作由应用程序通过线程库完成
线程切换在用户态下即可完成,不需要改变状态
操作系统无法感知线程的存在

用户级线程优缺点如下
优点:用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高
缺点:当一个用户级线程被阻塞后,整个进程都会被阻塞,并发度不高。多个线程不可在多核处理机上并行运行

内核级线程(KLT):其线程的管理工作由操作系统内核完成,线程调度、切换工作均由内核完成,因此各项工作需要在核心态下才能完成
线程的管理工作由操作系统内核完成
线程调度、切换等工作都由内核负责,因此内核级线程的切换必然需要在核心态下才能完成
操作系统会为每个内核级线程建立相应的线程控制块(TCB)来完成对线程的管理
内核级线程”就是“从操作系统内核视角看能看到的线程”

内核级线程优缺点如下
优点:当一个线程被阻塞后,别的线程还可以继续执行,并发能力强。多线程可在多核处理机上并行执行
缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大。

多线程模型

一对一模型:一个用户级线程映射到一个内核级线程。每个用户进程都有与用户级线程同等数量的内核级线程
优点:当一个线程被阻塞时,别的线程还可以继续执行,并发能力强。多线程可以在多核处理机上并行运行
缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统完成,需要切换到核心态,因此线程管理的成本高,开销大

多对一模型:多个用户级线程映射到一个内核级线程。每个用户进程;每个用户进程只对应一个内核级线程;线程管理工作在用户空间完成,此模式中,用户级线程对操作系统透明
优点:用户级线程的切换在用户空间即可完成不需要切换到核心态,线程管理的系统开销小,效率高
·缺点:当一个用户级线程被阻塞后,整个进程会被阻塞,并发度不高。多个线程不可以在多核处理机上并发运行

多对多模型:n用户级线程映射到m个内核级线程(n>=m)。每个用户进程对应m个内核级线程
特点:克服了多对一模型中并发度不高的缺点,又克服了一对一模型中一个用户进程占用太多内核级线程,开销太大的缺点。