操作系统——管程

管程作为解决进程同步和互斥的一种机制,通过封装共享数据结构和相关操作,使得生产者和消费者问题得以简化。在管程中,同一时间只有一个进程能执行其内部函数,确保了对共享资源的互斥访问。Java等语言提供了类似管程的机制,使得程序员只需调用预定义的过程即可实现复杂的并发控制。管程的设计降低了编程复杂性,提高了代码的可读性和可维护性。
摘要由CSDN通过智能技术生成

文章目录


一、管程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
管程的定义和基本特征:

消费者和生产者共享缓冲区。
管程提出的背景:PV操作对于解决进程互斥和进程同步编程复杂,因而提出了管程。
管程当中定义了共享数据结构只能被管程内部定义的函数所修改,所以如果我们想修改管程内部的共享数据结构的话,我们只能调用管程内部提供的函数来间接的修改这些数据结构。
管程内部虽然定义了很多函数,但是同一时刻一定只有一个进程使用管程中的一个函数,别的进程如果也想使用管程内部的某个函数的话,只要之前的进程还没有用完,别的进程就暂时不能执行管程的这些函数。
在这里插入图片描述
为什么管程要这样设计呢?

假如我们把生产者和消费者当中的缓冲区定义为管程当中的某一种共享数据结构,那按照之前我们学习的内容,各个进程对缓冲区的访问必须是互斥的,也就是有一个进程在访问缓冲区的时候,别的进程不能同时访问缓冲区,必须先进行等待。如果我们能保证每次仅有一个进程能在管程当中的某一个内部过程执行的话,那么这就意味着每一次对共享数据结构的访问肯定只有一个进程正在执行,而不可能有多个进程同时在访问共享数据结构,所以这就是管程的精髓所在。

管程是怎么解决生产者和消费者问题的?
在这里插入图片描述
生产者把产品放入缓冲区,只需要调用insert函数就可以,不需要编写PV操作来管理互斥和同步,这里insert函数就会实现。
此外,如果一个进程正在访问管程的话,另外一个进程也访问管程,编译器会负责实现各进程之间的互斥。
在这里插入图片描述
第一个消费者在执行的时候,首先调用了管程的remove过程或者这个函数,此时会判断缓冲区中是否有可用的产品,由于刚开始count的值为0,所以第一个消费者进程会执行wait等待操作,在consumer1消息队列中进行等待,同样的第二个消费者进程开始执行remove函数的时候也会发现此时count的值是0,所以他也需要执行等待操作,同样的也会插入到empty条件变量对应的队尾consumer2。之后如果有一个生产者进程开始执行,他会执行管程的insert函数或者这个过程,他会把它生产的产品放入缓冲区当中并且会检查自己放入的产品是不是缓冲区的第一个产品,如果是的话代表此时有可能有别的消费者进程正在等待我的这个产品,所以接下来生产者进程在执行insert函数的时候,也会在其中执行一个唤醒操作(signal),用于唤醒等待在empty当中的条件变量对应的某一个进程,一般来说会唤醒在队头的进程,也就是第一个消费者进程,由于第一个消费者进程被唤醒了之后,他就可以往下执行,首先执行count–,让count的值由1变成了0,然后再检查自己再取走这个产品之前缓冲区是不是已经满了,如果缓冲区之前已经是满的,那么就意味着有可能有生产者进程被唤醒,于是消费者进程又会调用一个signal(full),最后remove函数会返回一个消费者进程想要的产品对应的指针。

也就是进程只需要调用remove,里面的互斥和同步问题都由管程来解决。

所以可以看到,在采用了管程之后,实现进程的同步和互斥就变得简单了,只需要调用管程当中的一些过程来完成我们想要完成的事情就可以了。
在这里插入图片描述
java中类似于管程的机制
在这里插入图片描述
总结:
在这里插入图片描述
入口指的就是管程内部定义的函数。

管程其实就是利用程序封装的思想,把进程同步互斥这些复杂的细节隐藏在了管程定义的函数之内,而对外只提供一个简单易用的函数调用的接口。

总结

主要学习了管程,重点在于管程的基本特征。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值