一、进程与线程
1.进程的概念与特征
为了更好地描述和控制程序的并发执行,实现操作系统的并发性和共享性,引入了进程的概念。
a.进程的概念
进程控制快(PCB):为了更好的描述进程的基本情况和运行状态,进而控制和管理进程。(PCB是进程的唯一标志)
进程的一些典型定义:
(1)进程是程序的一次执行过程。
(2)进程是一个程序及其数据在处理机上顺序执行时所发生的活动。
(3)进程是具有独立功能的程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。
b.进程的特征
进程的基本特征是对比单个程序的顺序执行提出的,也是对进程管理提出的基本要求:
(1)动态性:动态性是进程最基本的特征,进程有着创建、活动、暂停、终止等过程,具有生命周期。
(2)并发性:多个进程实体同时存在内存中,引入进程的目的就是为了程序与其他程序并发执行。
(3)独立性:进程实体是一个能够独立运行、独立获得调度的基本单位。没有建立PCB的程序,都不能作为一个独立单位参与运行。
(4)异步性:进程相互制约,进程以不可预知的速度向前推进,所以操作系统中一定要配置响应的进程同步机制。
(5)结构性:每个进程都要配置一个PCB对其进行描述(进程实体包括程序段、数据段和进程控制段)
2.进程的状态与转换
a.进程的状态
通常进程有以下5种状态,前三种是进程的基本状态:
(1)运行态:进程在处理机上运行。
(2)就绪态:进程已处于准备运行状态。
(3)阻塞态:又称等待态,进程正在等待某个时间而暂停运行。
(4)创建态:进程正在被创建,尚未进入就绪态。
(5)结束态:进程正在从系统中消失(包括正常结束或者异常终止)。
b.进程状态的转换
就绪态—>运行态:处于就绪态的进程获得处理机进入运行态。
运行态—>就绪态:处于运行态的进程时间片用完后,让处理机进入就绪态。
运行态—>阻塞态:进程请求除处理机意外的其他资源,此时运行态进入阻塞态(系统调用请求操作系统提供服务,这是一种特殊的、由运行用户态程序调用操作系统内核过程的形式)。
阻塞态—>就绪态:进程等待其他资源的获得。如IO资源或者中断结束。
3.进程控制
进程控制的主要功能是对系统中所有进程实施有效的管理,它具有创建新进程、撤销已有进程,实现进程状态转换等功能。在操作系统中一般把进程控制的程序称为原语,原语的特点是执行期间不允许中断,它是一个不可分割的基本单位。
a.进程的创建
在操作系统中,允许一个进程创建另一个进程,此时创建者被称为父进程,被创建的进程称为子进程。子进程可以继承父进程所拥有的所有资源。当子进程被撤销时,应将其从父进程那里获得的资源归还给父进程。此外,在撤销父进程时,必须撤销其所有进程。
在操作系统中,终端用户登录系统、作业调度、系统提供服务、用户程序的应用请求等都会引起进程的创建。
操作系统创建一个新进程的过程如下(创建原语):
(1)为新进程分配唯一地一个进程标识号,并申请一个空白的PCB(PCB是有限的)。
(2)为进程分配资源,为新进程的程序和数据以及用户栈分配必要的内存空间。
(3)初始化PCB,包括初始化标志信息、初始化处理机状态信息、出乎石化处理机控制信息、设置进程的优先级。
(4)若进程就绪队列可以接纳新进程,进程就进入就绪态。
b.进程的终止
引起进程结束的事件主要有:(1)正常结束,表示进程的任务已完成并准备退出运行。(2)异常结束,表示进程在运行时,发生了某种异常事件。(3)外界干预,指进程应外界的请求而终止运行。
引起操作系统终止进程的过程如下(撤销原语):
(1)根据被终止进程的标识符,检索PCB,读出进程的状态。
(2)若进程处于运行态终止运行剥夺处理机。
(3)终止进程之下的子进程。
(4)将该进程拥有的全部资源还给父进程或者操作系统、
(5)将PCB从队列中删除。
c.进程的阻塞和唤醒
正在执行的进程,由于期待的某些事件未发生,如:请求系统资源失败、等待某种操作的完成、新数据尚未到达或无新工作可做等,由系统自动执行阻塞原语(阻塞是一种自主行为,自我阻塞)。阻塞原语的执行过程如下:
(1)找到将要被阻塞进程的标识号对应的PCB。
(2)若该进程处于运行态,则保护其现场,将状态转换为阻塞态,停止运行。
(3)将PCB插入响应时间等待序列。
当被阻塞进程所期待的事件出现时,调用唤醒原语,将等待该事件的进程唤醒(唤醒是被相互有联系的其他进程进行唤醒)。唤醒原语的执行进程如下:
(1)找到等待队列中进程相应的PCB。
(2)将其从等待队列中移出,置其状态为就绪态。
(3)将PCB插入就绪队列,等待调度程序调度。
d.进程切换
进程切换是在内核台下完成的,引起进程切换的事件有:(1)当前进程的时间片用完。(2)更高优先级的进程到达。(3)当前进程主动阻塞。(4)当前进程终止。
进程切换的过程如下:
(1)保存处理机上下文,包括程序计数器和其他寄存器。
(2)更新PCB信息。
(3)把进程的PCB移入相应的队列,如就绪、在某事件阻塞等队列。
(4)选择另一个进程执行,并更新其PCB。
(5)更新内存管理的数据结构。
(6)恢复处理机上下文。
4.进程的组织
进程是一个独立的运行单位,也是操作系统进行资源分配和调度的基本单位,由进程控制块(PCB)、程序段和数据段三部分组成,其中最核心的是进程控制块。
进程的组织方式有两种,一种是链接方式,它按照进程状态将PCB分为多个队列,操作系统持有指向各个队列的指针。另一种是索引方式,它根据进程状态的不同,建立几张索引表,而操作系统持有指向各个索引表的指针。
a.进程控制块
进程创建时,操作系统为它新建一个PCB,该结构之后常驻内存,任意时刻都可以存取,并在进程结束时删除。PCB是进程实体的一部分,是进程存在的唯一标志。
进程控制块主要包括进程描述信息、进程控制和管理信息、资源分配清单和处理机相关信息等。各部分的说明如下:
进程描述信息:进程标识符用来标识各个进程,每个进程都有唯一的标识号。用户标识符即进程归属的用户,用户标识符主要为共享和保护服务。
进程和管理信息:进程当前状态用来描述进程的状态信息,作为处理及分配和调度的依据。进程优先级用来描述进程抢占处理机的优先级。
资源分配清单:用于说明有关内存地址空间或虚拟地址空间的状况,所打开文件的列表和所使用的输入/输出设备信息。
处理及相关信息:用来指出处理机中各寄存器的值。
b.程序段
程序段就是能被进程调度程序调度到CPU执行的程序代码段。程序可被多个进程共享,即多个进程可以运行同一个程序。
c.数据段
一个进程的数据段,可以使进程对应程序加工处理的原始数据,也可以是程序执行产生的中间或者最终结果。
5.进程的通信
进程通信是指进程之间的信息交换。PV操作是低级通信方式,高级通信方式是指以较高的效率传输大量数据的通信方式。高级通信方法主要有共享存储。消息传递和管道通信三种。
a.共享存储
在通信进程之间存在一块可以被直接访问的共享空间,共享存储又分为两种,低级方式的共享是基于数据结构的共享,高级方式的共享则是基于存储区的共享。操作系统只负责为通信进程提供可共享使用的存储空间和同步互斥工具,数据交换则由用户自己安排读/写指令完成。
b.消息传递
在消息传递系统中,进程间的数据交换是以格式化的消息为单位的。若通信的进程之间不存在可直接访问的共享空间,则必须利用操作系统提供的消息传递方法实现进程通信。进程通过系统发送信息和接受信息两个原语进行数据交换。
(1)直接通信方式:发送进程直接发送信息给接收进程,并把它挂在接收进程的消息缓冲队列上,接收进程从消息缓冲队列中获取消息。
(2)间接通信方式:发送进程把消息发送给某个中间实体,接收进程(从管道中接受消息。如电子邮件系统。
c.管道通信
管道是指用于连接一个读进程和一个写进程以实现他们之间的通信的一个共享文件,名为pipe文件。发送进程(写进程)以字符流的形式将大量数据送入写管道,接收进程(读进程)从管道中接收数据。当管道写满时,写进程的write()系统调用将被阻塞,等待读进程将数据取走。当读进程将数据全部取走后,管道变空,此时读进程的read()系统调用将被阻塞。
管道机制提供的三种协调能力:互斥、同步和确认对方存在。
从本质上说,管道也是一种文件,但它又与一般的文件不同**,管道可以克服使用文件通信的两个问题:1.限制管道的大小。2.读进程也可能比写进程快**。
从管道读数据时一次性操作,数据一旦被读取,他就从管道中被抛弃,释放空间以便写更多的数据,因此管道只能进行半双工通信,要实现父子进程双方互动通信,就必须定义两个管道。
6.线程概念和多线程模型
a.线程的基本概念
引入进程的目的是更好的使用多道程序并发执行,提高系统的资源利用率和吞吐量。引入线程的目的是为了减小程序在并发执行时所付出的时空开销,提高操作系统的并发性能。
线程是一个基本的CPU执行单元,也是程序执行流的最小单元,由线程ID、程序计数器、寄存器集合和堆栈组成。线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可以与同时一个进程的其他县城共享进程所拥有的全部资源。由于线程之间的相互制约,致使线程在运行中存在间断性。线程也有就绪、阻塞和运行三种基本状态。
b.线程与进程的比较
(1)调度。线程是独立调度的基本单位,进程是拥有资源的基本单位。在同一进程中,线程的相互切换,不会引起进程的相互切换。在不同进程中,线程的相互切换会引起进程的相互切换。
(2)拥有资源。进程是拥有资源的基本单位而线程不拥有系统资源(只拥有一点儿必不可少的资源)单线程可以访问其他隶属进程的系统资源。
(3)并发性。不仅进程之间可以并发执行,多个线程之间也可以并发执行。
(4)系统开销。同一进程的线程切换要比进程切换开销小得多。
(5)地址空间和其他资源。进程的地址空间相互独立,同一进程的各线程之间共享进程的资源,某进程的线程对其他进程不可见。
(6)通信方面。进程之间的通信需要进程同步和互斥手段的辅助,保证数据的一致性,线程之间可以直接使用读/写手段来进行通信。
c.线程的属性
(1)线程是一个轻型实体,不拥有系统资源,拥有唯一标识符和线程控制块。
(2)不同的线程可以执行相同的程序,同一个服务程序的不同用户调用时,操作系统为其创建不同的线程。
(3)同一进程的不同线程共享给进程拥有的全部资源。
(4)线程是处理机独立调度的基本单位,多个线程是可以并发执行的。
(5)线程在生命周期内也会经历阻塞、运行和就绪等状态的变化。
d.线程的实现方式
线程的实现可以分为两类:用户级线程和内核级线程。
在用户级线程中有关线程管理的工作都由应用程序完成,内核意识不到线程的存在。
在内核级线程中,线程管理的工作由内核完成,应用程序没有进行线程管理代码,只有一个到内核级线程的编程接口。
e.多线程模型
有些系统同时支持用户线程和内核线程,由此产生了不同的多线程模型,即实现用户级线程和内核级线程的连接方式。
(1)多对一模型。将多个用户级线程,映射到一个内核级线程,线程管理在用户空间完成,用户线程对操作系统不可见。优点线程管理在用户空间上进行,效率比较高。缺点:一个线程阻塞全部线程阻塞,多个线程不能并行运行在多处理机上。
(2)一对一模型。每个用户线程都映射到一个内核级线程。优点:并发能力强。缺点:创建线程开销大,影响应用程序的性能。
(3)多对多模型。多个线程映射到多个内核线程上,结合了上述两种模型,既提高了并发性,又适当降低了开销。
二、处理及调度
1.调度的概念
a.调度的基本概念
调度是指合理的对进程进行处理机的分配。
处理机调度是多道程序操作系统的基础,是操作系统设计的核心问题。
b.调度的层次
作业调度(高级调度):从辅存中选择作业送入内存,每个作业之调入一次,调出一次。
中级调度(内存调度):提高内存利用率和系统吞吐量,将暂时不能运行的进程调至外存,使其进入挂起态,或者将已经具备运行条件的进程调入内存,修改器状态为就绪态。
进程调度(低级调度):按照某种策略或者方法从就绪队列中选取一个进程,将处理机分配给他(最基本的调度,进程调度的频率很高)。
c.三级调度的联系
作业调度从外存的后备队列中选择一批作业进入内存,为他们建立进程,进程调度从就绪队列中选出一个进程,并把其状态改为运行态,吧CPU分配给它,中级调度是为了提高内存的利用率,系统讲那些不能运行的进程挂起来,当内存空间宽松时,通过中级调度选择具备条件的进程,将其唤醒。
(1)作业调度为进程活动做准备,进程调度使进程正常活动起来,中级调度将暂时不能运行的进程挂起,中级调度处于作业调度和进程调度之间。
(2)作业调度次数少,中级调度次数略多,进程调度频率最高。
(3)进程调度是最基本的不可或缺的。
d.调度的时机、切换与过程
现代操作系统中,不能进行进程调度的情况有以下几种:
(1)在处理中断的过程中。
(2)进程在操作系统内核程序的临界区中。
(3)其他需要完全屏蔽的原子操作过程中。
应该进行进程调度与切换的情况如下:
(1)发生引起调度条件且当前进程无法继续运行下去时,可以马上进行调度与切换。
(2)中断处理结束或者自陷处理结束后,返回被中断进程的用户态程序执行现场前,若置上请求调度标志,即可马上进行调度与切换。
2.进程调度的方式
所谓进程调度的方式就是指当某个进程正在处理机上执行时,若有某个更为紧要或紧迫的进程需要处理,此时应如何分配处理机。通常由以下两种进程调度的方式:
(1)非剥夺调度方式,又称非抢占方式。即只允许进程主动放弃处理机。
(2)剥夺调度方式,又称抢占式。即进程可以被动放弃处理机。
3.调度的基本准则
在选择调度算法时,必须考虑算法的特性,为了比较调度算法的性能,人们制定了很多的评价标准,如以下这几种:
(1)CPU利用率,要尽可能保持CPU为忙碌的状态,使这一资源利用率最高。
(2)系统吞吐量,单位时间内CPU完成作业的数量。
(3)周转时间,作业提交到作业完成的时间。
周转时间=作业完成时间-作业提交时间 平均周转时间=总周转时间/N个作业
带权周转时间=作业周转时间/作业实际运行时间 平均带权周转时间=总周转时间/N个作业
(4)等待时间,作业等待处理机的时间,等待时间越长,用户满意度越低。
(5)响应时间,从用户请求到系统首次产生响应所用的时间。
4.进程的挂起与七状态模型
暂时调到外存等待的进程状态为挂起态,挂起态分为就绪挂起和阻塞挂起。
挂起和阻塞的区别:两种状态都是咱是不能获得CPU服务,但挂起态是将进程映像调到外存去了,而阻塞态进程映像还在内存中。
5.典型调度算法
a.先来先服务算法(FCFS)
FCFS调度算法是一种最简单的调度算法,且属于不可剥夺算法,它既可用于作业调度,也可用于进程调度。算法每次从后备队列中选择最先进入该队列的一个作业或几个作业,将他们调入内存,分配必要的资源,创建进程进入就绪队列。
FCFS算法的特点是算法简单,但是效率低,对长作业比较有利,但对短作业不利,有利于CPU繁忙型作业,不利于I/O繁忙型作业。
b.短作业优先算法(SJF)
短作业(进程)优先调度算法是指对短作业(进程)优先调度的算法。短作业优先算法(SJF)从后备队列中选择一个或若干个估计运行时间最短的作业,将它们调入内存运行。短进程优先调度算法(SPF)从就绪队列中选择一个估计运行时间最短的进程,将处理机分配给它,使之立即执行。
短作业优先算法的缺点:(1)对长作业不利,造成饥饿现象(2)没有考虑作业的紧迫性,因而不能保证紧迫性作业会被及时处理。(3)作业长短是由用户提供的预估时间而定的,因而无法做到真正的短作业优先。
注意:SJF算法的平均等待时间、平均周转时间最少。
c.优先级调度算法
优先级调度算法又称优先权调度算法,它既可用于作业调度,又可用于进程调度,该算法中的优先级用于描述作业运行的紧迫程度。
该调度算法可以分为两类,一类是非剥夺式优先级调度算法,该算法只能由于进程自身原因主动让出处理机。一类是剥夺式优先级调度算法,优先级高的进入就绪队列后可以抢占优先级低进程的处理机。
系统的优先级分为两种,一种是静态优先级,即进程创建后就无法对优先级进行修改。另一种动态优先级,可以根据进程的运行状态,动态的对优先级进行调整。
一般来说优先级的设置可以遵循以下原则:
1.系统进程>用户进程
2.交互型进程>非交互型进程
3.I/O进程>计算型进程(CPU繁忙型)
d.高响应比优先调度算法
高响应比优先算法属于非抢占式算法,主要用于作业调度。在每次进行作业调度时,先计算后备队列中每个作业的响应比,从中选出相应比最高的作业投入运行。
响应比=(等待时间+要求服务时间)/要求服务时间
高响应比优先调度算法的特点有:
(1)作业等待时间相同,要求服务时间越短,响应比越高,有利于短作业。
(2)要求服务时间相同时,比较等待时间,实现了先来先服务。
(3)对于长作业,只要其等待时间够长,响应比便可以提高,克服了饥饿问题。
e.时间片轮转算法(RR)
时间片轮转算法属于抢占式算法,且不会导致饥饿,就绪进程按照到达先后依次排成队列,依次在时间片内占用处理机,时间片到达时该进程就释放处理机给下一个就绪进程。
f.多级反馈队列调度算法
多级反馈队列调度算法的实现思想如下:
(1)设置多个就绪队列,并为多个队列赋予不同的优先级。
(2)赋予各个队列中进程执行时间片的大小各不相同。优先级越高的队列,时间片越小。
(3)一个新进程进入内存后,首先将他放入第1级队列的末尾,按照FCFS原则等待调度。若该进程在一个时间片内没有执行完成,则转入第2级队列的末尾。
(4)仅当第1级队列为空时,调度程序才调度第2级的对列中的进程运行。
多级反馈队列的优点:
(1)终端型作业用户,短作业优先。
(2)短批处理作业用户,周转时间短。
(3)长批处理作业用户:不会长期得不到处理(但是会导致饥饿)。
三、进程同步
1.基本概念
为了协助进程之间的相互制约关系,引入了进程同步的概念。
a.临界资源
一次只允许一个进程使用的资源被称为临界资源。
临界资源的访问过程分成如下四个部分:
(1)进入区:进程是否可以进入临界区,若能进入临界区则设置正在访问临界区的标志。
(2)临界区:可以访问临界资源的代码。
(3)退出区:将正在访问临界区的标志清除。
(4)剩余区:代码中的其余部分。
b.同步
同步亦称直接制约关系,是指为完成某种任务而建立的两个或多个进程,这些进程因为需要在某个位置上协调它们的工作次序而等待、传递消息所产生的制约关系。进程的直接制约关系来源于它们的合作。
c.互斥
互斥也称间接制约关系。当一个进程进入临界区使用临界资源时,另一个进程必须等待,当占用临界资源的进程退出临界区时,另一进程才允许访问此临界资源。
为禁止两个进程同时进入临界区,同步机制应该遵循以下规则:
(1)空闲让进。临界区空闲时允许一个请求进入临界区的进程立即进入临界区。
(2)忙则等待。当已有进程进入临界区时,其他试图进入临界区的进程必须等待。
(3)有限等待。对请求访问的进程,应保证能在有限时间内进入临界区。
(4)让权等待。当进程不能进入临界区时,应立即释放处理器,避免进程忙等待。
2.实现临界区互斥的基本方法
a.软件实现方法
(1)单标志法
单标志法的算法思想:两个进程在访问完临界区后会把使用临界区的权限转交给另一个进程,也就是说每个进程进入临界区的权限只能被另一个进程赋予。
但是当某个进程不再进入临界区时,另一个进程也无法进入临界区(违背了“空闲让进”)容易造成资源利用不充分。
(2)双标志法先检查
双标志先检查法的算法思想是:在每个进程访问临界区之前先查看临界资源是否被访问,若正被访问,该进程需要等待,否则进程才进入自己的临界区。为此,设置一个布尔数组flag[],数组中的各个元素表示某个进程想要进入临界区的意愿,每个进程进入临界区之前,先检查当前有没有别的进程想要进入临界区,如果没有便将自己的flag[i]标志位置为1,之后进入临界区。
该算法的优点是不用交替进入临界区。缺点是两个进程可能同时进入临界区(按照1234的顺序执行时)违背了“忙则等待”。
(3)双标志法后检查
双标志后检查法是双标志先检查法的改版,双标志先检查法先检查对方的标志位状态,再置自己的标志位,而双标志后检查法是先将自己的标志位置1,在检查对方的标志位状态。
虽然双标志后检查法解决了“忙则等待”的问题,但又违背了“有限等待”和“让权等待”的原则(1526的顺序执行时,二者均无法访问临界区),还会造成饥饿现象。
(4)Peterson算法
Peterson算法的算法思想:为了防止两个进程为进入临界区而无限等待,又设置了turn变量,每个进程在设置了自己的标志位后再设置turn标志。这时,再同时检测另一个进程状态标志和不允许进入标志,以便保证两个进程同时要求进入临界区时,只允许一个进程进入临界区。
Peterson算法使用软件方法解决了进程互斥问题,遵循了空闲让进、忙则等待和有限等待三个原则,但仍未遵循让权等待原则。Peterson算法虽然较其他几种算法来说是最好的,但又不够好。
b.硬件实现方法
(1)中断屏蔽法
当一个进程正在使用处理机执行它的临界区代码时防止其他进程进入其临界区进行访问的最简单方法是,禁止一切中断发生,称之为屏蔽中断、关中断。
中断屏蔽方法的优点是简单、高效。缺点是这种方法限制了处理机交替执行程序的能力,为此执行的效率会明显降低。
(2)TestAndSet指令
TestAndSet指令既是硬件指令也是原子操作,即执行该代码时不允许被中断,其功能是读出指定的标志后,将标志位置为真。可以为每个临界资源设置一个共享布尔变量lock,表示资源的两种状态:true表示正在被占用,false表示空闲。lock初值为false,在进程访问临界资源之前,利用TSL指令检查和修改标志lock,若有进程正在访问临界区,则重复检查,直到进程退出。
(3)Swap指令
Swap指令是硬件指令,即执行该代码时不允许被中断,该指令的功能是交换两个字(字节)的内容。
3.信号量
信号量机制是一种功能较强的机制,可以用来解决互斥和同步问题,他只能被两个标准的原语wait(S)和signal(S)访问,也可以记为“P操作”和“S操作”。(原语是指完成某种功能且不可被分割、不可被中断的操作序列,通常可由硬件指令完成)
a.整型信号量
用一个整数型的变量作为信号量,用来表示系统中某个资源的数量(与普通整数变量的区别:对信号量的操作只有三种:初始化、P操作和V操作)。
b.纪录型信号量
整型信号量的问题是会出现“忙等”问题(只要信号量S<0就会不断地测试),为此又提出了纪录型信号量机制。纪录型信号量不存在“忙等问题”,且遵循了“让权等待”的原则,除需要一个用于代表资源数目的整型变量value外,在增加一个进程链表L,用于链接所有等待该资源的进程。
纪录型信号量的说明:
c.利用信号量实现同步
进程同步:要让各并发进程按要求有序推进。
d.利用信号量实现进程互斥
信号量机制也可以很好地解决进程互斥问题,只需要把临界区置于P(S)和V(S)之间,即可实现两个进程对临界资源进行互斥访问。
e.利用信号量实现前驱关系
信号量也用来描述程序之间或语句之间的前驱关系,其实每一对前驱关系都是一种同步问题。
f.分析进程同步和互斥问题的步骤
(1)关系分析。找出问题中的进程数,并分析他们之间的同步和互斥关系。
(2)整理思路。设置解决问题的关键点,根据进程的操作流程确定P操作、V操作的大致顺序。
(3)设置信号量。根据上面的两个步骤,设置需要的信号量,确定初值,完善整理。
4.管程
由于信号量机制中,每个访问临界资源的进程都需要自备同步的PV操作,很容易产生死锁,因此产生了管程,管程的特性保证了进程互斥,无需程序员自己实现互斥,从而降低了死锁发生的可能。
a.管程的定义
管程是指一组数据以及定义在这组数据之上的对这组数据的操作组成的软件模块,这组操作能初始化并改变管程中的数据同步进程。
管程的组成:
(1)管程的名称。
(2)局部于管程的共享结构数据说明。
(3)对该数据结构进行操作的一组过程。
(4)对局部于管程内部的共享数据设置初始值的语句。
管程把对共享资源的操作封装起来,管程内的共享数据结构只能被管程内的过程所访问。每次仅允许一个进程进入管程,从而实现进程互斥。
b.条件变量
x.wait:当x对应的条件不满足时,正在调用管程的进程调用x.wait将自己插入到x条件的等待队列,并释放管程,此时其他进程可以使用该管程。
x.signal:x对应的条件发生了变化,则调用x.signal,唤醒了一个因x条件而阻塞的进程。
条件变量与信号量的比较:
相似点:条件变量的wait/signal操作类似于信号量的P/V操作,可以实现进程的阻塞和唤醒。
不同点:条件变量是“没有值的”,仅实现了“排队等待”的功能;而信号量是“有值的”,信号量反映了剩余资源的数目,而在管程中剩余资源数用共享数据结构记录。
四、死锁
1.死锁的概念
死锁是指多个进程因为竞争资源造成的一种僵局,没有外力作用,这些进程都无法向前继续推进。
死锁产生的原因有:1.系统资源的竞争。2.进程推进顺序非法。
死锁产生的必要条件:1.互斥条件:进程对分配资源进行排他性控制。2.不可剥夺条件:进程获得资源在未使用之前,不能被其他进程强行夺走。3.请求并保持条件:进程已经保持了至少一个资源,提出新的资源请求,而该资源已经被其他进程占有,此时该进程被阻塞,但是自己已经获得的资源保持不放。4.循环等待条件:循环等待链,你等我释放,我等你释放。
2.死锁的处理策略
a.死锁预防:设置某些限制条件,破坏产生死锁的4个必要条件中的一个或几个,以防止死锁的发生。
b.避免死锁:使用某种方法防止系统进入不安全状态,从而避免死锁。
c.死锁的检测及解除:允许发生死锁,通过检测及时地判断死锁,然后对其进行解除。
3.死锁的预防
a.破坏互斥条件
某些资源只能互斥使用,某些情况下必须保护其互斥性。
b.破坏不可剥夺条件
当一个已保持了某些不可剥夺资源的进程请求新资源而得不到满足时,它必须释放已经保持的所有资源,待以后需要时重新申请。
特点:增加了系统的开销,降低了系统的吞吐量,常用于状态易于保存和恢复的资源。
c.破坏请求和保持条件
采用预先静态分配方法,即进程在运行前就一次性申请完所有资源。
特点:实现简单,但是资源被严重浪费,甚至可能导致进程饥饿。
d.破坏循环等待条件
采用顺序资源分配法,首先给系统资源进行编号,规定每个进程按照编号递增的顺序对资源进行申请,同类资源一次性申请完。
4.死锁的避免
a.系统安全状态
所谓安全状态就是指系统能按照某种进程推进程序为每个进程分配其所需要的资源,直至满足每个进程对资源的最大需求,使每个进程都可按照顺序完成。此时称这个系列为安全序列,若系统无法找到一个安全序列,责成系统处于不安全状态。
并非所有的不安全状态都是死锁状态,但当进程进入不安全状态,便可能进入死锁状态。当进程处于安全状态时,便可以避免进入死锁状态。
b.银行家算法
进程运行之前先声明对各种资源的最大需求量,当进程在执行中继续申请资源时,先测试该进程已占用的资源数和本次申请资源之和是否超过该进程生命的最大需求量,若超过则拒绝分配资源,若未超过,则再测试系统现存的资源能否满足该进程尚需的最大资源量,若能满足则按照当前的申请量分配资源,否则也要推迟分配。
5.死锁的检测和解除
a.资源分配图
圆圈代表进程,框代表一类资源,进程到资源的有向边称为请求边,资源到进程的边称为分配边。
b.死锁定理
在资源分配图中找到分配满足的进程,然后消去其请求边与分配边,如果最后所有边都可以被消除,那么就是可以简化的,不存在死锁,否则存在死锁。
c.死锁解除
资源剥夺法:挂起某些死锁进程,抢占资源,将这些资源分配给其他死锁进程,但是要防止挂起时间过长。
撤销进程法:强制撤销部分甚至全部死锁进程,并且剥夺他们的资源,撤销原则可以根据优先级和撤销进程的代价进行。
进程回退法:让一个或者多个进程回退到足以回避死锁的地步,进程回退时,自动释放资源而非剥夺,要求系统保持进程历史信息,设置还原点。
d.死锁、饥饿、死循环的区别
死锁:各进程互相等待对方手里的资源,导致各进程都堵塞,无法向前推进的现象。
饥饿:由于长期得不到想要的资源,某个进程无法向前推进的现象。
死循环:某进程执行过程中一直跳不出某个循环的现象。