《操作系统》-管程

为什么要引入管程

信号量作为高层抽象与P、V操作一起来解决了绝大部分的进程同步问题。但这种解决方法也有一定的缺陷:
(1)程序易读性差,因为要了解对于信息量的操作是否正确需要读懂整个系统活着并发程序。
(2)程序不利于修改或维护,因为程序的局部性很差,所以对任意一组变量一段代码的修改都有可能影响全局。
(3)正确性难以保证,因为操作系统或并发程序通常很大,要保证这样一个复杂的系统,没有逻辑错误是很难的
(4)容易发生死锁的情况,如果程序员不使用好P、V操作时,逻辑上发生错误,很有可能会导致死锁的发生。

那么能不能设置一种机制,让程序员写程序时,不需要再关注复杂的PV操作,让写代码更轻松,二期不会轻易发生死锁呢?
这就是我们接下来介绍的于1973年,Brinch Hansen 首次在程序设计语言(Pascal)中引入了“管程”成分——一种高级同步机制

管程的定义和基本特征

一个管程是由一个过程、变量及数据结构组成的一个集合,他们组成一个特殊的模块或软件包。 进程可在任何需要的时候调用管程中的过程来访问、调用管程中的数据结构注意:过程只能是管程中声明的才行
管程是一种特殊的软件模块,有这些部分组成:
1.局部于管程的共享数据结构说明
2.对该数据结构进行操作的一组过程
3.对局部于管程的共享数据结构设置初始值的语句
4.管程有一个名字

管程的基本特征:
1.管程是一个基本的软件模块,可以被单独编译
2.管程中封装的数据以及对数据的操作,与面向对象编程语言的类相似
3.局部于管程的数据只能被局部于管程的过程所访问
4.一个进程只能通过调用管程内的过程才能进行管程访问共享数据
5.每次允许一个进程在管程内执行某个内部过程

条件变量

1.enter进程
进程在进入管程之前要提前申请,一般由管程提供一个外部过程——enter过程。进程调用管程中的enter过程即可进入管程
2.leave过程
当进程离开管程时,如果紧急队列不为空,那么它就必须负责唤醒紧急队列中对头的进程,此时也是由管程提供的外部过程——leave过程。
3.条件型变量c
条件型变量c实际上是一个指针,它指向一个等待该条件的PCB队列。假设缓冲区已满用full,缓冲区已空用empty,当进程要往缓冲区写入数据时,若此时缓冲区已满,则用wait(full)将该进程加入full指向的紧急队列,如此时该缓冲区恰好只占用一个缓冲区单元,则在写入数据后,使用signal(empty)释放当前进程并调用empty的紧急队列的第一个进程。当进程在缓冲区读数据时,若缓冲区为空时,则使用wait(empty)将该进程指向empty的紧急队列,若在该进程读数据后,缓冲区不满则使用signal(full)释放当前进程并调用full紧急队列的第一个进程0
4.wait( c )
wait( c )表示为进入管程的进程分配某种类型的资源,如果此时这种资源可用,那么进程使用,否则进程被阻塞,进入紧急队列
5.signal( c )
signal( c )表示进入管程的进程某种资源释放,此时进程会唤醒由于等待这种资源而进入紧急队列的第一个进程

扩展1:用管程解决生产者消费者问题

在这里插入图片描述
引入管程的目的无非就是要方便实现进程的互斥和同步
1.需要在管程中定义共享数据(如生产者消费者问题的缓冲区)
2.需要在管程中定义于访问这些共享数据的“入口”——其实就是一些函数(如生产者消费者问题中,可以定义一个函数用于将产品放入缓冲区,再定义一个函数用于从缓冲区中取出产品)
3.只有通过这些特定的入口才能访问共享数据
4.管程中有很多“入口”,但是每次只开放其中一个“入口”,并且只能让一个进程或线程进入(如生产者消费者问题中,各进程需要互斥的访问共享缓冲区。管程的这些特征即可保证一个时间段内最多只会有一个进程访问缓冲区。注意:这种互斥特性是由编译器进行实现的,程序员不用关心
5.可在管程中设置条件变量等待/唤醒操作以解决同步问题。可以让一个进程或线程在条件变量上等待(此时,该进程应先释放管程的使用权,也就是让出“入口”);可以通过唤醒操作将等待在条件变量上的进程或线程唤醒
程序员可以用某种特殊的语法定义一个管程,之后其他程序员就可以使用管程提供的特定“入口”(封装思想)很方便地使用实现进程同步/互斥了。

扩展二:Java中类似于管程的机制

1.Java中每个对象都有一个内置锁,所以可以更简单的实现管程,不过要添加条件变量需要设置一个可重入锁ReentrabtLock()
2.如果关键字synchronized来描述一个函数,那么这个函数同一时间段内只能被一个线程调用
3.条件变量获取方式Condition notFull = lock.newCondition();
在这里插入图片描述

信号量与管程的比较

信号量与管程本质上是互通的,他们都能解决同步问题,但是我们需要注意的是信号量并不能解决所有同步问题,下面我们来说说两者的区别:

  • 信号量本质是指可共享的资源数量,而管程是一种抽象的数据结构
  • 信号量是可以并发执行的,而管程内部只能互斥的进行访问
  • 信号量的V操作唤醒其他线程后,当前线程与其他线程并发的执行,而管程的signal操作,会释放当前线程,唤醒条件变量紧急队列中的第一个线程执行操作,他并非并发执行的
  • 信号量P操作不一定会堵塞,但管程的wait操作一定会堵塞
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

电脑小白路过

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值