更新时间:2023-05-16 11:12
管程在功能上和信号量及PV操作类似,属于一种进程同步互斥工具,但是具有与信号量及PV操作不同的属性。
信号量机制的缺点:进程自备同步操作,P(S)和V(S)操作大量分散在各个进程中,不易管理,易发生死锁。1974年和1977年,Hore和Hansen提出了管程。
管程特点:管程封装了同步操作,对进程隐蔽了同步细节,简化了同步功能的调用界面。用户编写并发程序如同编写顺序(串行)程序。
引入管程机制的目的:1、把分散在各进程中的临界区集中起来进行管理;2、防止进程有意或无意的违法同步操作;3、便于用高级语言来书写程序,也便于程序正确性验证。
管程是由局部于自己的若干公共变量及其说明和所有访问这些公共变量的过程所组成的软件模块。
1)局部于管程的共享变量;
2)对数据结构进行操作的一组过程;
3)对局部于管程的数据进行初始化的语句。
共享性:管程可被系统范围内的进程互斥访问,属于共享资源
安全性:管程的局部变量只能由管程的过程访问,不允许进程或其它管程直接访问,管程也不能访问非局部于它的变量。
互斥性:多个进程对管程的访问是互斥的。任一时刻,管程中只能有一个活跃进程。
封装性:管程内的数据结构是私有的,只能在管程内使用,管程内的过程也只能使用管程内的数据结构。进程通过调用管程的过程使用临界资源。管程在Java中已实现。
(1)局部数据和条件变量组成管程内的数据结构;
(2)过程/函数1~过程/函数k组成管程内的一组过程对管程内的数据结构进行操作;
(3)初始化代码对管程内的数据结构进行初始化。
管程是互斥进入的,所以当一个进程试图进入一个巳被占用的管程时它应当在管程的入口处等待,因而在管程的入口处应当有一个进程等待队列,称作入口等待队列。
管程是用于管理资源的,当进入管程的进程因资源被占用等原因不能继续运行时使其等待,即将等待资源的进程加入资源等待队列,该队列由条件变量维护。资源等待队列可以由多个,每种资源一个队列。
条件变量(例如名称为c)是管程内的一种数据结构,且只有在管程中才能被访问,它对管程内的所有过程是全局的,只能通过两个原语操作来控制它。
c.wait( )-调用进程阻塞并移入与条件变量c相关的队列中,并释放管程,直到另一个进程在该条件变量c上执行signal( )唤醒等待进程并将其移出条件变量c队列。
c.signal( )-如果存在其他进程由于对条件变量c执行wait( )而被阻塞,便释放之;如果没有进程在等待,那么,信号被丢弃。
条件变量与P、V操作中信号量的区别:
条件变量是一种信号量,但不是P、V操作中纯粹的计数信号量,没有与条件变量关联的值,不能像信号量那样积累供以后使用,仅仅起到维护等待进程队列的作用。因此在使用条件变量x时,通常需要定义一个与之配套使用的整型变量x-count用于记录条件变量x所维护等待队列中的进程数。
当一个进入管程的进程执行等待操作wait时,其它进程应该被允许进入管程;
当一个进入管程的进程执行唤醒操作signal时(如P唤醒Q),管程中便存在两个同时处于活动状态的进程,由于任一时刻,管程中只能有一个活跃进程。所以处理办法为:
1)P等待Q继续,直到Q退出或等待
2)Q等待P继续,直到P等待或退出
3)规定唤醒signal为管程中最后一个可执行的操作
Hoare管程数据结构
信号量mutex管理管程入口处的等待队列,供管程中过程互斥调用,初值为1。
进程调用管程中的任何过程时,应执行P(mutex);进程退出管程时应执行V(mutex)开放管程,以便让其他调用者进入。
为了使进程在等待资源期间,其他进程能进入管程,故在wait操作中也必须执行V(mutex),否则会妨碍其他进程进入管程,导致无法释放资源。
执行wait操作的进程需要释放信号量mutex,不在mutex信号量上等待,而在其它条件变量(或信号量)上等待。
信号量next管理管程内的紧急等待队列其初值为0,凡发出signal操作的进程应该用P(next)挂起自己,加入紧急等待队列,直到被释放进程退出管程或产生其他等待条件。
进程在退出管程的过程前,须检查是否有别的进程在信号量next(即紧急等待队列)上等待,若有,则用V(next)唤醒它。next-count初值为0,用来记录在next (即紧急等待队列)上等待的进程个数。
信号量x-sem用来管理资源等待队列,其初值为0,进程申请资源得不到满足时,执行P(x-sem)挂起,加入x-sem所代表的资源队列。由于释放资源时,需要知道是否有别的进程在等待资源,用计数器x-count(初值为0)记录等待资源(即资源等待队列中)的进程数。
执行signal操作时,应让等待资源(即资源等待队列中)的诸进程中的某个进程立即恢复运行,而不让其他进程抢先进入管程,这可以用V(x-sem)来实现。