管程
设计目的
- 将分散在各进程中的临界区集中起来管理
- 避免进程有意无意的违法同步操作
- 便于用高级语言来书写程序
定义
管程是由局部于自己的若干公共变量及其说明和所有访问这些公共变量的过程所组成的软件模块
形式结构
条件变量
条件变量是出现在管程内的一种数据结构,只能在管程中被访问,对管程内的所有过程是全局的,只能通过两个原语操作来控制它。
- wait?:阻塞调用进程并释放管程,直到另一个进程在条件变量c上执行signal
- signal?: 如果存在其他进程由于对条件变量c执行wait()而被阻塞,便释放对应进程;如果没有进程在等待,那么信 不被保存。
霍尔管程
可以注意到:当使用signal释放等待进程时,可能出现两个进程同时停留在管程内
霍尔管程:执行signal的进程等待,直到被释放进程退出管程或wait其他条件
实现
- 使用PV操作源于来实现对管程中过程的互斥调用,以及实现对共享资源互斥使用的管程
- 不要求signal操作时过程体的最后一个操作,切wait和signal操作可被设计成可中断的过程
数据结构
mutex
对每个管程,使用用于管程中过程互斥调用的信 量mutex(初值为1)
- 进程调用管程中任意过程时,应执行P(mutex)
- 进程退出管程时,需要判断是否有进程在next信 量等待
- 如果有(next_count>0),则通过V(next)唤醒一个发出signal的进程
- 否则应执行V(mutex)开放管程,让其他进程进入
- 为了使进程在等待资源期间(阻塞),其他进程能进入管程,所以在wait操作中也必须执行V(mutex),否则会妨碍其他进程无法进入管程,导致无法释放资源
next和next_count
对每个进程引入信 量next(初值为0)
- 凡发出signal操作的进程应该用P(next)阻塞自己,直到被释放进程退出管程或产生其他等待条件
- 进程退出管程前,需要检查是否有别的进程在信 量next上等待
- 若有(next_count>0),则用V(next)唤醒它
- next_count用于记录next上等待的进程个数
x_sem和x_count
引入信 量x_sem(初值为0)
- 申请资源得不到满足时,执行P(x_sem)阻塞
- x_count用于记录等待资源的进程数
- 执行signal操作时,应让等待资源的进程们中的某个进程立即恢复运行,而不是让其他进程抢先进入管程,用V(x_sem)实现
标准模板
哲学家就餐问题
五个人围成一圈,间隔放五把叉子,每个人需要两把叉子才能吃饭
同步问题
生产者消费者问题
type pc=MONITOR{ item buffer[k]; //缓冲区结构 int putptr=0,getptr=0,count=0; //存取指针以及计数 semaphore full=0,empty=0; int full_count=0,empty_count=0; InterfaceModule IM; define add,take; use enter,leave,wait,signal;}void add(item &x){ enter(IM); if(count==k)wait(empty,empty_count,IM); //缓冲区已满 item[putptr]=x; putptr=(putptr+1)%k; count++; signal(full,full_count,IM); //唤醒等待的消费者 leave(IM);}void take(item &x){ enter(IM); if(count==0)wait(full,full_count,IM); x=item[getptr]; getptr=(getptr+1)%k; count--; signal(empty,empty_count声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!