目录
前趋图
程序执行
程序顺序执行
程序并发执行
进程
定义
进程控制块 PCB
进程实体
进程
特征
动态性
并发性
独立性
异步性
状态
3 种基本状态
就绪状态
执行状态
阻塞状态
3 种基本状态间的转换
其他状态
创建状态
终止状态
进程 5 种状态及其转换关系
挂起操作
引入
3 个基本状态间的转换
5 个基本状态间的转换
进程管理中的数据结构
OS 中用于管理资源和控制进程的数据结构
进程表 PCB
作用
PCB 中的信息
进程标识符
处理机状态
进程调度信息
进程控制信息
组织方式
线性方式
链接方式
索引方式
进程控制
进程的创建
进程的层次结构
进程图
引起进程创建的事件
进程的创建过程
进程的终止
引起进程终止的事件
正常结束
异常结束
外界干预
进程的终止过程
进程的阻塞与唤醒
引起进程阻塞与唤醒的事件
进程的阻塞过程
进程的唤醒过程
进程的挂起与激活
进程的挂起
进程的激活
进程通信
分类
低级进程通信
高级进程通信
类型
共享存储器系统
管道通信系统
消息传递系统
客户机 - 服务器系统
套接字
远程过程调用和远程方法调用
消息传递通信的实现方式
直接通信(直接消息传递系统)
直接通信原语
对称寻址方式
非对称寻址方式
消息的格式
定长消息格式
变成消息格式
进程的同步方式
通信链路
间接通信(信箱通信)
信箱的结构
信箱通信原语
信箱的创建和撤销
消息的发送和接收
信箱的类型
线程
线程的引入
进程的两个基本属性
进程是一个可拥有资源的独立单位
进程是一个可独立调度和分派的基本单位
程序并发执行所须付出的时空开销
线程——作为调度和分配的基本单位
线程与进程的比较
状态
执行的 3 个基本状态
执行状态
就绪状态
阻塞状态
线程控制块 TCB
TCB 中的信息
线程标识符
一组寄存器的内容
线程执行状态
优先级
线程专有存储器
信号屏蔽
堆栈指针
多线程 OS 中的进程属性
进程是一个可拥有资源的基本单位
多个线程可并发执行
进程已不是可执行的实体
线程的属性
线程的实现
实现方式
内核支持线程 KST
KST 的实现方式的主要优点
主要缺点
用户级线程 ULT
优点
缺点
两种线程的组合方式 ULT/KST 线程
多对一模型
一对一模型
多对多模型
具体实现
KST 的实现
ULT 的实现
运行时系统
核心线程 LWP
线程的创建与终止
线程的创建
线程的终止
定义:指一个有向无环图
作用:描述进程之间执行的先后顺序
符号含义:
表示:程序之间的前趋关系可用“→”表示,(Pi,Pj)∈ →
,Pi → Pj
,Pj 开始执行之前 Pi 必须执行完成,Pi 是 Pj 的直接前趋,Pj 是 Pi 的直接后继
初始节点:没有前趋的节点
终止节点:没有后继的节点
权重:每个节点具有一个权重,表示该节点所含有的程序量或程序的执行时间
例子:
注意:前趋图中不允许有循环,否则会产生无法实现的前趋关系
定义:一个程序由若干个程序段组成,每个程序段负责完成特定的功能,且他们需要按照某种先后次序被顺序运行,仅当前一程序段运行完成后,才会运行后一程序段。即使是一个程序段,也可能存在执行顺序问题
特征:
条件:只有不存在前趋关系的程序才有可能并发执行
特征:
程序在并发执行时,由于失去了封闭性,其计算结果与并发程序的执行速度有关,使程序的执行失去了可再现性。即程序经过多次执行后,虽然多次执行时的环境和初始条件相同,但得到的结果却不同
定义:在 OS 中为使参与并发执行的每个程序都能独立地运行,必须配置的一个专门的数据结构
作用:描述进程的基本情况和活动过程,进而控制和管理进程
地位:进程存在的唯一标志
别称:进程映像
简称:进程
定义:由程序段、相关的数据段和 PCB 这 3 部分便构成了进程实体【PCB 是给操作系统用的,程序段、数据段是给进程自己用的】
创建进程:实质上是创建进程的 PCB
撤销进程:实质上是撤销进程的 PCB
进程:进程是进程实体的运行过程,是系统进行资源分配和调度(进程被调度是指操作系统决定让此进程上CPU运行)的一个独立单位
从不同的角度有不同的定义,较典型的定义有:
传统 OS 中的进程:是程序的执行过程,是系统进行资源分配和调度的一个独立单位
进程与程序的区别:
地位:因为进程的实质是程序的执行过程,所以动态性是进程最基本的特征
表现:进程由创建而产生,由调度而执行,由撤销而消亡
程序:一组有序指令的集合,存放于某种介质上,本身不具有活动的含义,是静态的
定义:指多个进程共存于内存中,且能在一段时间内同时执行
地位:并发性是进程的另一个重要特征,OS 的重要特征
程序(未建立 PCB):不能参与并发执行
定义:指进程是一个能够独立运行、独立获得资源、独立接受调度的基本单位
程序(未建立 PCB):不能作为一个独立的单位参与并发执行
定义:指进程是按异步方式运行的,即按各自独立的、不可预知的速度向前推进
定义:指进程已处于准备好执行的状态,即进程已分配到除 CPU 以外的所有必要资源后,只要再获得 CPU,便可立即执行
就绪队列:若系统中有许多处于就绪状态的进程,则通常会将它们按一定的策略排成一个队列
定义:指进程获得 CPU 后其程序“正在执行”的状态
PS:对于任一时刻,在单处理机系统中,只有一个进程处于执行状态,在多处理机系统中,可能会有多个进程处于执行状态
定义:正在执行的进程由于发生某事件而暂时无法继续执行,即指进程的执行受到了阻塞。此时会引发进程调度,OS 会把处理机分配给另一个就绪进程,而让受阻进程处于暂停状态,此状态称为阻塞状态 / 等待状态 / 封锁状态
阻塞队列:将处于阻塞状态的进程排成一个队列
PS:在较大的系统中,为了减少阻塞队列操作开销,提高系统效率,根据阻塞原因的不同,设置多个阻塞队列
就绪 —> 执行:处于就绪状态的进程,在调度程序为之分配处理机之后便可执行,其状态由就绪变为执行
执行 —> 就绪:正在执行的进程,若因分配给它的时间片已完而被剥夺处理机暂停执行时,其状态由执行变为就绪
执行 —> 阻塞:若因发生某事件而致使当前进程的执行受阻,使之无法继续执行,则该进程状态将由执行转变为阻塞
进程的产生:进程是由创建或新建产生的
创建进程的过程:
引入目的:保证进程的调度必须在创建工作完成后进行,以确保对 PCB 操作的完整性;增加了管理的灵活性,OS 可以根据系统性能或内存容量的限制,推迟新进程的提交(使进程处于创建状态)
创建 —> 就绪:处于创建状态的进程,当其获得了必需的资源,并完成了对 PCB 的初始化工作后,便可由创建状态转入就绪状态
进程终止的步骤:
定义:当一个进程到达了自然结束点,或出现了无法克服的错误,或被 OS 所终止,或被其他有终止权的进程所终止时,进入的状态
PS:进入终止状态的进程不能再被执行,但在 OS 中仍保留记录,会保存状态码和一些计时统计数据以供其他进程收集。一旦其他进程完成对其信息的提取,系统就会删除该进程,即将其 PCB 清零,并将该空白 PCB 返还 OS
当挂起操作作用于某个进程时,该进程将被挂起,意味着此时该进程处于静止状态
引入挂起操作主要是为了满足以下需求:
挂起原语 Suspend
激活原语 Active
活动就绪状态:进程处于未被挂起的就绪状态,表示为 Readya,此时进程可以接受调度
静止就绪状态:使用挂起原语将处于活动就绪状态的进程挂起后,该进程的状态为静止就绪状态,表示为 Readys,此时进程不会被调用执行
活动阻塞状态:进程处于未被挂起的阻塞状态,表示为 Blockeda
静止阻塞状态:使用挂起原语将处于活动阻塞状态的进程挂起后,该进程的状态为静止阻塞状态,表示为 Blockeds,处于该状态的进程在其所期待的事件发生后,将从静止阻塞状态变为静止就绪状态
活动就绪 —> 静止就绪:使用挂起原语将处于活动就绪状态的进程挂起后,变成静止就绪状态
活动阻塞 —> 静止阻塞:使用挂起原语将处于活动阻塞状态的进程挂起后,变成静止阻塞状态
静止阻塞 —> 静止就绪:处于静止阻塞状态的进程在其所期待的事件发生后,变成静止就绪状态
静止就绪 —> 活动就绪:使用激活原语将处于静止就绪状态的进程激活后,变成活动就绪状态
静止阻塞 —> 活动阻塞:使用激活原语将处于静止阻塞状态的进程激活后,变成活动阻塞状态
NULL —> 创建:一个新进程产生时,该进程处于创建状态
创建 —> 活动就绪:在当前系统的性能和内存容量均允许的情况下,当完成进程创建的必要操作后,相应地系统会将进程状态转换为活动就绪状态
创建 —> 静止就绪:在当前的系统资源状况和性能要求不允许的情况下,系统不会分配给新建进程所需资源(主要是内存),相应地系统会将进程状态转换为静止就绪状态。进程被安置在外存,不参与调度,此时进程创建工作尚未完成
执行 —> 终止:当一个进程已完成任务,或出现无法克服的错误,或被 OS 或其他进程所终止时,将进程状态转换为终止状态
为了便于使用和管理计算机中各类资源(包括硬件和信息),OS 将其抽象为相应的各种数据结构,并提供了一组对资源进行操作的命令
资源信息表和进程信息表:在计算机系统中,对于每个资源和每个进程都设置了一个数据结构,用于表征其实体
组成:资源和进程的标志、描述、状态等信息以及一批指针
指针的作用:将同类资源和进程的信息表,或同一进程所占用的资源信息表分类链接成不同的队列,以便 OS 进行查找
OS 管理的控制表:内存表、设备表、文件表和用于进程管理的进程表 PCB
便于系统描述和管理进程
PCB 作为进程的一部分,记录了 OS 所需的、用于描述进程当前情况以及管理进程运行状态的全部信息,是 OS 中最重要的记录型数据结构
具体作用:
作用:用于唯一地标志一个进程
类型:
处理机状态信息,也称为处理机的上下文
组成:主要由处理机的各种寄存器中的内容组成
处理机包含的寄存器:
定义:指用于进程控制所必需的信息
描述:将系统中所有的 PCB 都组织在一张线性表中,将该表起始地址存放在内存的一个专业区域中
优点:实现简单且开销小
缺点:每次查找时都需要扫描整张表
适应范围:进程数目不多的系统
描述:通过 PCB 中的链接字,将具有相同状态的进程的 PCB 分别链接成一个队列,即可形成就绪队列、若干个阻塞队列和空闲队列……
就绪队列:按进程的优先级将 PCB 从高到低进行排列,即优先级高的进程的 PCB 排在队列的前面
阻塞队列:根据阻塞原因的不同,把处于阻塞状态的进程的 PCB 排成多个阻塞队列
描述:系统根据所有进程状态的不同,建立几张索引表,并把各索引表在内存中的起始地址记录在内存的一些专用单元中。在每个索引表的表目中,记录具有相应状态的某个 PCB 在 PCB 表中的位置
定义:进程管理中最基本的功能,负责创建新进程、终止已完成的进程、将因发生异常情况而无法继续运行的进程置于阻塞状态、转换运行中进程的状态
PS:进程控制一ru般是由 OS 内核中的原语实现的
如何实现原语的“原子性”?
原语的执行具有原子性,即执行过程只能一气呵成,期间不允许被中断
可以用“关中断指令”和“开中断指令”这两个特权指令实现原子性
解释:假设这是正在运行的内核程序,CPU 会依次运行以上指令,并且 CPU 每执行完一条指令后,都会例行检查是否有中断信号的存在,当指令2执行完成之后,CPU 检查到中断信号的存在,CPU 暂停执行当前程序,转而执行处理中断的程序,当中断处理完成之后才会回到原来的程序继续执行
正常情况:CPU 每执行完一条指令都会例行检查是否有中断信号需要处理,若有,则暂停运行当前这段程序,转而执行相应的中断处理程序
解释:当 CPU 执行关中断指令之后,将不再例行检查中断信号,虽然指令 a 后存在一个中断信号,但是不会对其进行处理,直到执行开中断指令之后,CPU 才会意识到之前的一个中断信号还没有处理,转向执行中断处理程序
结论:当 CPU 执行了关中断特权指令之后,CPU 不再例行检查中断信号,直到执行开中断指令之后才会恢复检查;在关中断和开中断之间的指令序列是不可被中断的,可以实现“原子性”
进程控制原语所完成的事:
形成:在 OS 中,运行一个进程创建另一个进程,通常把创建进程的进程称为父进程,把被创建的进程称为子进程,子进程可以继续创建其自己的子进程(即父进程的孙进程),由此形成进程的层次结构
子进程可以继承父进程所拥有的资源
当子进程被撤销时,应将其从父进程那里获得的资源归还给父进程
在撤销父进程时,也必须同时撤销其所有的子进程
为标志进程间的家族关系,在 PCB 中设置家族关系表项,标明自己的父进程及所有的子进程
进程不能拒绝其子进程的继承权
Windows 系统中不存在任何进程层次结构的概念,所有的进程都具有相同的地位
目的:形象地描述一个进程的家族关系
定义:用于描述进程间关系的一棵有向树
节点:代表进程
有向边:指明进程间的父子关系
树的根节点:进程家族的祖先
以上均由系统内核为用户创建一个新进程
在系统中每当出现创建进程的请求时,OS 便会调用进程创建原语,按以下步骤创建一个新进程:
当进程创建新进程时,有两种执行的可能:
新进程的地址空间也有两种可能:
含义:表示进程的任务已经完成,准备退出运行
指示进程运行完成:任何系统都应有一个用于表示进程已经运行完成的指示
含义:指进程在运行时,发生了某种异常事件,使程序无法继续执行
常见的异常事件:
含义:指进程应外界的请求而终止运行
存在的干预:
当系统中发生了要求终止进程的某事件后,OS 便会调用进程终止原语,按以下步骤终止指定的进程:
正在执行的进程,若发生了上述某事件,进程便会通过调用阻塞原语 block 将自己阻塞,故阻塞是进程自身的一种主动行为
进入 block 阶段后,由于该进程还处于执行状态,因此系统应:
PS:若系统中设置了因不同事件而阻塞的多个阻塞队列,应将该进程插入具有相同事件的阻塞队列
当被阻塞进程所期待的事件发生时,有关进程就会调用唤醒原语 wakeup 将等待该事件的进程唤醒,wakeup 的执行过程是:
PS:block 原语和 wakeup 原语是一对作用刚好相反的原语,必须成对使用,否则阻塞进程将会因不能被唤醒而永久地处于阻塞状态,再无机会继续运行
当系统中出现引发进程挂起的事件时,OS 就会利用挂起原语 suspend 将指定进程或处于阻塞状态的进程挂起。suspend 的执行过程是:
当系统中出现激活进程的事件时,OS 就会利用激活原语 active 将指定进程激活。active 的执行过程是:
假如采用的是抢占调度策略,则每当有静止就绪进程被激活而插入就绪队列时,便会检查是否要进行重新调度,即由调度程序将被激活进程与当前进程两者的优先级进行比较,如果被激活进程的优先级较低,则不必重新调度;否则,立即终止当前进程的运行,并把处理机分配给刚被激活的进程
定义:指进程之间的信息交换
进程是分配系统资源的单位(包括内存地址空间),因此各进程拥有的内存地址空间相互独立
为了保证安全,一个进程不能直接访问另一个进程的地址空间
低级进程通信低级的原因:
高级通信工具的主要特点:
设置一个共享内存区域,并映射到进程的虚拟地址空间
要互斥地访问共享空间,由通信进程自己负责实现互斥
相互通信的进程共享某些数据结构或存储区,进程之间能够通过这些空间进行通信
管道:指用于连接一个读进程和一个写进程以实现二者之间通信的一个共享文件,又名 pipe 文件
管道通信:向管道(共享文件)提供输入的发送进程(即写进程),会以字节流形式将大量的数据送入管道;而接收管道输出的接收进程(即读进程),则会从管道中接收读数据。由于发送进程和接收进程是利用管道进行通信的,故称之为管道通信
优点:有效地传送大量数据
为了协调双方的通信,管道机制必须提供的协调能力:
采用数据流的方式,数据的读写是先进先出
管道只能采用半双工通信,某一时间段内只能实现单向的传输,若要实现双向同时通信,则需要设置两个管道
管道中的数据一旦被读出,就彻底消失,因此,当多个进程读同一管道时,可能会错乱。对此,通常有两种解决方案:①一个管道允许多个写进程,一个读进程(408真题) ②允许有多个写进程,多个读进程,但系统会让各个读进程轮流从管道中读数据(现实应用)
描述:在该机制中,进程不必借助任何共享数据结构或存储区,而是以格式化的消息为单位,将通信的数据封装在消息中,并利用 OS 提供的一组通信命令(原语),在进程间进行消息传递,完成进程间的数据交换
高级通信方式
优点:隐藏了通信实现细节,使通信过程对用户透明,降低了通信程序设计的复杂性和错误率
根据实现方式分为:
设计目的:被用于同一台主机上多个应用程序之间的通信(即进程间的通信),主要是为了解决对进程同时通信时端口和物理线路的多路复用问题
一个套接字就是一个通信标志类型的数据结构
组成:通信目标地址、通信使用的端口号、通信网络的传输层协议、进程所在的网络地址以及针对客户或服务器程序所提供的不同系统调用或 API ……
地位:进程通信和网络通信的基本构件
分类:
优点:不仅适用于同一台计算机内部的进程通信,也适用于网络环境中不同计算机间的进程通信
远程过程调用:一个通信协议,用于通过网络连接的系统。允许运行于一台主机(本地)系统上的进程调用另一台主机(远程)系统上的进行,对程序员表现为常规的过程调用,无须额外为此编程。若涉及的软件采用面向对象编程,则远程过程调用可称作远程方法调用
网络守护进程:负责处理远程过程调用的进程,一个是本地客户进程,一个是远程服务器进程,主要负责在网络间传递信息,一般均处于阻塞状态,等待信息
存根:在本地客户端,每个能独立运行的远程过程都拥有一个客户存根,本地进程调用远程过程,实际是调用该过程关联的存根;在每个远程进程所在的服务器端上,其所对应的实际可执行进程存在一个服务器存根与其关联。本地客户存根与对应的远程服务器存根一般处于阻塞状态,等待消息
远程过程调用步骤的重点:客户端的本地过程调用 —> 客户存根 —> 服务器端的本地过程调用
调用者在整个过程中不知道该过程的执行在远程而非本地
进程之间通信时,源进程可以直接或间接地将消息发送给目标进程,故将进程通信分为直接和间接两种,直接消息传递系统和信箱通信分别采用二者
直接消息传递系统采用直接通信方式,即发送进程利用 OS 所提供地发送命令(原语),直接把消息发送给目标进程
要求:发送进程和接收进程都必须以显式方式提供对方的标识符
通信命令(原语):
send(receiver,message)
:发送一个消息给接收进程receive(sender,message)
:接收发送进程发来的消息缺点:一旦改变进程的名称,需要检查所有其他进程的定义,有关对该进程旧名称的所有引用都必须查找到,以便将其修改为新名词,此方式不利于实现进程定义的模块化
无法指定发送进程
send(P,message)
:发送一个消息给进程 P
receive(id,message)
:接收来自任何进程的信息,id 变量可设置为进行通信的发送方进程 id 或其名字
应用:单处理机系统
优点:采用比较短的定长消息格式,减少对消息的处理和存储开销,可用于办公自动化系统,为用户提供快速的信笺式通信
缺点:对于需要发送较长消息的用户不方便
描述:进程所发送消息的长度是可变的
优点:方便用户
缺点:无论在处理方面还是存储方面,都会付出更多的开销
当进程之间进行通信时,需要有进程同步机制,使得各进程间能协调通信。无论是发送进程还是接收进程,在完成消息的发送或接收后,都存在两种可能,即进程继续发送/接收,或者阻塞
3 种情况:
建立目的:使发送进程和接收进程之间可以进行通信
建立方式:
通信方式:
信箱通信采用间接通信方式,即进程之间的通信需要通过某种中间实体实现。该实体建立在随机存储器的共享缓冲区上,用来暂存发送进程发送给目标进程的消息;接收进程从该实体中取出发送进程发送给自己的消息,通常把中间实体称为信箱 / 邮箱,每个信箱有一个唯一的标识符。消息在信箱中可以被安全保存,只允许核准的目标用户对其进行随时存取。所以,利用信箱通信方式既可实现实时通信,又可实现非实时通信
在逻辑上,可以分为两个部分:
消息传递的方式:
创建:进程可以利用信箱创建原语建立一个新信箱,创建者进程应给出信箱名字、信箱属性,对于共享信箱,还应给出共享者的名字
撤销:当进程不再需要读信箱时,可用信箱撤销原语将其撤销
当进程之间要利用信箱进行通信时,必须使用共享信箱,并利用系统提供的原语进行通信
send(mailbox,message)
:将一个消息发送到指定信箱
receive(mailbox,message)
:从指定信箱中接收一个信箱
信箱可由 OS 创建,也可由用户进程创建,创建者是信箱的拥有者
根据信箱的创建者,可将信箱分为:
利用信箱通信时,在发送进程和接收进程之间,存在的关系:
线程是一个基本的 CPU 执行单元,也是程序执行流地最小单位
引入进程的目的:使多个程序能并发执行,以提高资源利用率和系统吞吐量
引入线程的目的:减少程序在并发执行时所付出的时空(时间和空间)开销,使 OS 具有更好的并发性
由于进程具有这两个基本属性,所以进程成为一个能独立运行的基本单位,从而构成进程并发执行的基础
一个进程要能独立运行,就必须拥有一定的资源,包括用于存放程序正文和数据的磁盘,内存地址空间,以及其在运行时所需要的 I/O 设备、已打开的文件、信号量……
一个进程要能独立运行,必须是一个可独立调度和分派的基本单位
每个进程在系统中均有唯一的 PCB,系统可以根据 PCB 感知进程的存在,也可以根据 PCB 中的信息对进程进行调度,还可将断点信息保存在进程的 PCB 中。反之,可利用进程 PCB 中的信息恢复进程运行的现场
由于进程是一个资源的拥有者,所以在创建、撤销和切换中,系统必须为之付出较大的时空开销,因此限制了系统中所设置进程的数目,且进程切换不宜过于频繁,从而限制了程序并发执行的进一步提高
将进程的两个基本属性分开,使线程作为调度和分派的基本单位
线程具有传统进程所具有的很多特征,故称为轻型进程或进程元,相应地把传统进程称为重型进程
比较项目 |
进程 |
线程 |
调度的基本单位 |
在传统 OS 中,进程作为独立调度和分派的基本单位,能够独立运行。每次被调度时,都需要进行上下文切换,开销较大 |
在引入线程的 OS 中,把线程作为调度和分派的基本单位,因而线程是能独立运行的基本单位。当进行线程切换时,仅须保存和设置少量寄存器的内容,切换代价远低于进程。在同一进程中,线程的切换不会引起进程的切换,但从一个进程中的线程切换到另一个进程中的线程时,会引起进程的切换 |
并发性 |
传统进程机制中,只能进程间并发 |
在引入线程的 OS 中,进程之间可以并发执行,一个进程中的多个线程之间可并发执行,一个进程中的所有线程都能并发执行,不同进程中的线程能并发执行,使得 OS 具有更好的并发性,从而能更加有效地提高资源利用率和系统吞吐量 |
拥有资源 |
进程可以拥有资源,并作为系统中拥有资源的一个基本单位 |
线程几乎不拥有资源,仅有确保自身能够独立运行的资源。允许多个线程共享其共属的进程所拥有的资源,表现为:①属于同一进程的所有线程都具有相同的地址空间,意味着线程可以访问该地址空间中的每一个虚地址 ②线程可以访问其所属进程所拥有的资源 |
独立性 |
每个进程拥有独立的地址空间和其他资源,除了共享全局变量外,不允许自身以外的进程访问自己地址空间中的地址 |
同一进程中的不同线程之间的独立性,要比不同进程之间的独立性低得多。同一进程中的不同线程,是为了提高并发性和满足进程间的合作需求创建的,可共享进程的内存地址空间和资源 |
系统开销 |
创建(撤销)进程时,系统为其分配(向其回收)TCB 和其他资源;在进程进程切换时,涉及进程上下文的切换 |
OS 为线程创建/撤销时所付出的开销明显小于进程创建/撤销时所付出的开销;线程的切换代价远低于进程;由于一个进程中的多个线程具有相同的地址空间,线程之间的同步和通信比进程简单;在一些 OS 中,线程的切换、同步和通信无须 OS 内核的干预 |
支持多处理机系统 |
在多处理机系统中,对于传统的进程,即单线程进程,不管有多少处理机,该进程只能运行在一个处理及上 |
在多处理机系统中,对于多线程进程,可以将一个进程中的多个线程分配到多个处理及上并行运行,加速进程的完成 |
定义:指线程已获得处理机而正在执行
定义:指线程已具备各种执行条件,只须再获得 CPU 便可立即执行
定义:指线程在执行中因某事件而受阻,进而处于暂停状态
作用:将所有用于控制和管理线程的信息均记录在 TCB 中
为每个线程赋予一个唯一的线程标识符
包括程序计数器、状态寄存器、通用寄存器……
描述线程正处于何种执行状态
描述线程执行的优先程度
用于在线程切换时存放现场保护信息和与该线程相关的统计信息……
对某些信号加以屏蔽
线程在执行时,经常会进行过程调用,而过程调用时通常会出现多重嵌套的情况,必须把每次过程调用中所使用的局部变量以及返回地址保存起来。
为每个线程设置一个堆栈,用于保存局部变量和返回地址。
相应地,在 TCB 中设置两个指向堆栈的指针:指向用户自己堆栈的指针和指向核心栈的指针,前者是指当线程运行在用户态时,使用用户自己的用户栈保存局部变量和返回地址;后者是指当线性运行在内核态时,使用系统的核心栈保存局部变量和返回地址
在多线程 OS 中,进程仍作为系统资源分配的基本单位
任一进程所拥有的资源包括:用户的地址空间、实现进程(线程)间同步和通信的机制、已打开的文件和已申请到的 I/O 设备以及一张由核心进程维护的地址映射表(用于实现用户程序的逻辑地址到其内存物理地址的映射)
一个进程包含若干个相对独立的线程,其数目可少可多,但至少有一个线程
在 OS 中的所有线程都只能属于某一个特定进程
单线程方法:传统进程的执行方法
多线程方法:每个进程支持多个线程执行的方法
在多线程 OS 中,把线程作为独立运行(或称调度)的基本单位,此时进程已不再是一个基本的可执行实体
但是,进程仍具有与“执行”相关的状态,如:进程处于“执行”状态,实际上是指进程中的某线程正在执行
对进程所施加的、与进程状态有关的操作,也会对其线程起作用,如:把某个进程挂起,该进程中的所有线程都将被挂起;把某个进程激活,属于该进程的所有线程都将被激活
内核支持线程,在内核的支持下运行的,其创建、阻塞、撤销和切换……都在内核空间实现
内核级线程的切换在核心态下完成
为了对内核支持线程进行控制和管理,在内核空间为某个内核支持线程设置一个 TCB,内核根据该 TCB 感知某线程的存在,并对其加以控制
当前大多数 OS 支持 KST
对于用户的线程切换而言,其模式切换的开销较大;在同一个进程中,从一个线程切换到另一个线程时需要从用户态转到内核态进行,因为用户进程的线程在用户态运行,而线程调度和管理是在内核中实现,系统开销较大
用户级线程,在用户空间中实现,其对线程的创建、撤销、同步与通信等功能无须内核支持,与内核无关
用户级线程中,线程切换可以在用户态下即可完成,无需 OS 的干预
一个系统中的用户级进程的数目可以达到数百个甚至数千个
由于线程的 TCB 都设置在用户空间,而线程所执行的操作无须内核支持,故内核完全不知道用户级线程的存在
对于设置用户级线程的系统,其调度仍以进程为单位进行的
在组合方式线程系统中,内核支持多个 KST 的建立、调度和管理,允许用户应用程序建立、调度和管理 ULT
一些 KST 对应多个 ULT,ULT 通过时分多路复用 KST 来实现的,即将 ULT 对部分或全部 KST 进行多路复用,且程序员可按应用需要和机器配置对 KST 的数目进行调整,以达到较好的效果
在组合方式线程中,同一个进程内的多个线程可以同时在多处理机上并行执行,而且在阻塞一个线程时,并不需要将整个进程阻塞
由于 ULT 和 KST 的连接方式不同,从而形成了 3 种不同的多线程模型:多对一模型、一对一模型和多对多模型
描述:将多个 ULT 映射到一个 KST 上,这些 ULT 一般属于一个进程,运行在该进程的用户空间,对这些线程的调度和管理在该进程的用户空间中完成。仅当 ULT 需要访问内核时,才会将其映射到一个 KST 上,但每次只允许一个线程进行映射
OS 只看得见内核级线程,故只有内核级线程才是处理机分配的单位
主要优点:线程管理的开销小,效率高
主要缺点:若一个线程在访问内核时发生阻塞,则整个进程都会被阻塞;在任一时刻,只有一个线程能够访问内核,多个线程不能同时在多个处理机上运行
描述:将每个 ULT 映射到一个 KST 上,为每个 ULT 都设置一个 KST 与之连接,每个用户进程由与用户线程同数量的内核级线程
主要优点:当一个线程阻塞时,允许调度另一个线程运行,提供了比多对一模型更好的并发性能;在多处理机系统中,允许多个线程并行地运行在多处理机系统上
唯一缺点:每创建一个 ULT,相应地需要创建一个 KST,开销较大,故需要限制整个系统的线程数
描述:将许多 ULT 映射到同样数量或较少数量的 KST 上,KST 的数目根据应用进程和系统的不同而变化,其可以比 ULT 数少,也可以与之相等
内核级线程是处理机分配的单位
优点:既可以像一对一模型那样使一个进程的多个线程并行地运行在多个处理机系统上,又可以像多对一模型那样减少线程管理开销并提高效率
进程和线程均可直接或间接地取得内核支持
KST 可直接利用系统调用为其服务,故其对应的线程控制相当简单
ULT 必须借助于某种形式的中间系统的帮助才能取得内核的服务,故其对应的线程控制较复杂
系统在创建一个新进程时,便为其分配一个任务数据区 PTDA,其中包括若干个 TCB 空间,每个 TCB 中可保存线程标识符、优先级、线程运行的 CPU 状态……信息,虽然该信息与 ULT 的 TCB 中的信息相同,但其被保存在内核空间中
当进程创建一个线程时,便为新线程分配一个 TCB,同时将其有关信息填入该 TCB,并为之分配必要的资源。当 PTDA 中的所有 TCB 空间已用完而进程要创建新的线程时,只有其所创建的线程数目未超过系统的允许值,系统即可再为之分配新的 TCB 空间;在撤销一个线程时,应回收该线程的所有资源和 TCB。KST 的创建和撤销与进程的相似。在有的系统中,为了减少在创建和撤销一个线程时的开销,在撤销一个线程时,并不会立即回收该线程的资源和 TCB,当以后再创建一个新线程时,便可直接将已被撤销但仍持有资源的 TCB 作为新线程的 TCB
KST 的调度和切换与进程的调度和切换相似,分抢占式和非抢占式两种
ULT 在用户空间实现,所有 ULT 都具有相同的结构,都运行在一个中间系统上,当前有两种方式实现的中间系统,即运行时系统与核心线程
实质:用户管理和控制线程的函数的集合,包括用于创建和撤销线程的函数、用于控制线程同步和通信的函数以及用于实现线程调度的函数……因为有这些函数,才使 ULT 与内核无关。运行时系统中的所有函数都驻留在用户空间,并作为 ULT 与内核之间的接口
ULT 切换无须转入内核态,由运行时系统中的线程切换过程执行切换任务,该过程将线程的 CPU 状态保存在该线程的堆栈中,按照一定的算法选择一个处于就绪状态的新线程运行,并将新线程堆栈中的 CPU 状态装入 CPU 相应的寄存器中,一旦将栈指针和程序计数器切换后,便开始新线程的运行,由于 ULT 的切换无须进入内核,且切换操作简单,因而切换速度非常快
系统资源由内核管理,在传统的 OS 中,进程利用 OS 提供的系统调用请求系统资源,系统调用通过软中断机制进入 OS 内核,由内核完成相应资源的分配。ULT 不能利用系统调用,当线程需要系统资源时,须将该要求传送给运行时系统,由后者通过相应的系统调用获得系统资源
每一个进程都可拥有多个 LWP,同 ULT 一样,每个 LWP 都有自己的数据结构,其中包括线程标识符、优先级、CPU 状态……信息,还有栈和局部存储器
LWP 可共享进程所拥有的资源
LWP 通过系统调用获得内核提供的服务,当一个 ULT 运行时,须将其连接到一个 LWP上,便具有 KST 的所有所属,这种线程实现方式是组合方式
不可能设置太多的 LWP,会把这些 LWP 作为一个缓冲区,称为“线程池”,用户进程中的任一 ULT 都可连接到线程池中的任一 LWP 上。为使每个 ULT 都能利用 LWP 与内核通信,可以使多个 ULT 多路复用一个 LWP,但只有当前连接到 LWP 上的 ULT 才能与内核通信,其余线程或阻塞、或等待 LWP
每个 LWP 都要连接到一个 KST 上,通过 LWP 可把 ULT 与 KST 连接起来,ULT 可通过 LWP 访问内核,但内核所看到的总是多个 LWP 而非 ULT。即,由 LWP 实现了内核与 ULT 之间的隔离,从而使 ULT 与内核无关
当 ULT 不需要与内核通信时,不需要 LWP;当其要通信时,须借助 LWP,且每个要通信的 ULT 都需要一个 LWP
在 KST 执行操作时,若其发生阻塞,则与之相连的多个 LPW 也将阻塞,进而使连接到 LPW 上的 ULT 被阻塞。若进程中只包含一个 LWP,此时进程会被阻塞。与传统 OS 一样,在进程执行系统调用时,该进程实际上是阻塞的,但若一个进程中含有多个 LWP,当一个 LWP 阻塞时,进程中的另一个 LWP 可以继续执行;即使进程中的所有 LWP 全部阻塞,进程中的线程仍能继续执行,只是不能访问内核
线程有生命期,由创建而产生,由终止而消亡
在 OS 中有用于创建线程的函数(或系统调用)和用于终止线程的函数(或系统调用)
初始化线程:应用程序启动时正在执行的线程,其主要功能是创建新线程
在创建新线程时,需利用一个线程创建函数(或系统调用),并提供相应的参数
在线程的创建函数执行完后,将返回一个线程标识符供以后使用
当一个线程完成了自己的任务后,或是线程在运行中出现异常情况须被强行终止时,由终止线程通过调用相应的函数对其执行终止操作。但有些线程(主要是系统线程)一旦被建立起来后,便会一直运行下去而不被终止。大多数 OS 中,线程被终止后不会立即释放其所占有的资源,只有当进程中的其他线程执行分离函数后,被终止的线程才会与资源分离,此时的资源才能被其他线程利用
已被终止但尚未释放资源的线程,可被需要它的线程所调用,使其重新恢复运行。调用线程须调用一条“等待线程终止”的连接命令,与该线程进行连接。当一个调用线程调用“等待线程终止”的连接命令而试图与指定线程相连时,若指定线程尚未被终止,则调用连接命令的线程将会阻塞,直至指定线程被终止后,才能与指定进程进行连接并继续执行;若指定线程被终止,则调用线程不会被阻塞,则会继续执行