Operating System-进程/线程内部通信-管程(Monitor)介绍,实现以及应用
本文主要内容:
- 管程(Monitor)介绍
- 管程实现
- 管程应用
一、管程(Monitor)介绍
1.1 管程
前一篇文章介绍了信号量以及使用,信号量已经提供了一个方便且高效的进程同步机制,但是信号量有个缺点就是每次都需要程序员专门的去调用PV操作,如果程序员由于大意调用错了PV操作,比如该调用P操作的时候却调用了V操作,该针对X信号量调用P操作,却对Y信号量调用了P操作。这种错误是非常危险的,因为进程同步的问题不是每次都能重现,比如前面的错误在测试环境可能不会出现错误,但是到了生产环境就有可能出现,且无法重现。
为了解决上述问题,引入了管程(Monitor),信号量是操作系统层面的结构,管程是一个程序结构,由编程语言封装,最终由编译器:
- 一个管程定义了一个数据结构和能够并发进程所执行的一组操作,这组操作能同步进程和改变管程中的数据
- 进程可以调用管程的操作,但是不能访问管程的内部数据结构
- 它表示一个对象自己维护自己的状态,并且能够根据自身状态来同步并发的线程操作,而不是把这种同步的手段交给调用者来处理。
- 管程保证同一时间只有一个进程处在管程内部的方法内
monitor MonitorName
{
//shared variable declarations
procedure P1(...)
{ }
procedure P2(...)
{ } procedure P3(...)
{ } procedure PN(...)
{ } initialization code(...)
{ }
}
1.2 条件(Condition variables)
只有管程是不够的,在生产者消费者的例子中,当发现buffer中如果已经没有item的时候,消费者如何block自己呢?介于这个原因,又引入了条件变量(Condition Variables)。条件变量同时提供了两个方法:P以及V用于block和unblock。
二、管程实现
管程通过队列来跟踪那些尝试着想访问管程的进程,为了排他访问,管程必须得有一个锁,访问管程的进程会得到这个锁,其他尝试访问管程的进程就得block。被block的进程会被放入队列,等待被unblock。
管程的实现中有如下的队列:
- 进入队列(Entry Queue),保存尝试从外部访问管程程序的进程,每个管程至少有一个进入队列
- 被唤醒的队列(Signaller Queue),保存刚刚执行了V操场的进程(signal)
- 等待队列(Waiting Queue),保存刚刚被V操作唤醒的进程
- 条件变量队列(Condition Variable Queue),保存刚刚执行了条件变量Wait(P)操作的进程
三、管程应用
上一篇文章针对哲学家用餐给出的解决方案有个问题:当所有哲学家同时拿起筷子想吃饭的时候就会发生死锁,所有哲学家都会一直处于等待状态。本文用管程给出了解决方案,哲学家吃饭得满足的条件:
- 哲学家饿(hungry)
- 哲学家的左右邻居都没有吃饭
如果满足上面条件,则哲学家便可以拿起筷子进行用餐,否则哲学家就得等待
monitor dp
{
enum {thinking, hungry, eating} state[];
condition self[]; void pickup(int i) {
state[i] = hungry;
test(i);
if (state[i] != eating)
self[i].wait();//P操作
} void putdown(int i) {
state[i] = thinking;
test( (i+)% );
test( (i+)% );
} void test(int i) {
if ((state[(i+)%] != eating) &&
(state[i] == hungry) &&
(state[(i+)%] != eating)) {
state[i] = eating;
self[i].signal();//V操作
}
} void init() {
for (int i = ; i < ; i++)
state[i] = thinking;
}
}
Condition Self代表五个哲学家,当不能吃时候进行wait。
db.pickup(i);//找筷子
...
eating//吃
...
dp.putdown(i);//放下筷子
管程更多的是对资源的并发访问做了一次封装,感觉有很多OO编程的思想,直接用信号量的话,各种控制会很发散,当然容易出错,信号量本事是没有问题的。但是使用容易出错。且由于散发在多出,出问题不好排查,也不好修复。
管程是一种编程思想,这种思想就是封装,并且有DRY的感觉。
Operating System-进程/线程内部通信-管程(Monitor)介绍,实现以及应用的更多相关文章
- 突破python缺陷,实现几种自定义线程池 以及进程、线程、协程的介绍
Python线程 Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. #!/usr/bin/env python # -*- coding:utf-8 -*- import t ...
- python进程.线程和协程的总结
I.进程: II.多线程threading总结 threading用于提供线程相关的操作,线程是应用系统中工作的最小单位(cpu调用的最小单位). Python当前版本的多线程没有实现优先级,线程组, ...
- python系列7进程线程和协程
目录 进程 线程 协程 上下文切换 前言:线程和进程的关系图 由下图可知,在每个应用程序执行的过程中,都会去产生一个主进程和主线程来完成工作,当我们需要并发的执行的时候,就会通过主进程去生成一系列的 ...
- Python 进程、线程、协程的介绍与使用
一.必备的理论基础 二.操作系统发展史 三.进程理论 四.线程理论 五.协程 一.必备的理论基础 操作系统理论: 操作系统是一个协调\管理\控制计算机硬件资源与应用软件资源的控制程序 操作系统的两大功 ...
- 进程线程协程补充、docker-compose一键部署项目、搭建代理池、requests超时设置、认证设置、异常处理、上传文件
今日内容概要 补充:进程,线程,协程 docker-compose一键部署演示 搭建代理池 requests超时设置 requests认证设置 requests异常处理 requests上传文件 内容 ...
- Linux查看进程线程个数
1.根据进程号进行查询: # pstree -p 进程号 # top -Hp 进程号 2.根据进程名字进行查询: # pstree -p `ps -e | grep server | awk '{pr ...
- Python之路第一课Day9--随堂笔记之二(进程、线程、协程篇)
本节内容 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者消费者模型 Queu ...
- Python之路,Day9, 进程、线程、协程篇
本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者 ...
- Python学习之路--进程,线程,协程
进程.与线程区别 cpu运行原理 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者消费者模型 Q ...
随机推荐
- python中初始化实例属性
虽然我们可以自由地给一个实例绑定各种属性,但是,现实世界中,一种类型的实例应该拥有相同名字的属性.例如,Person类应该在创建的时候就拥有 name.gender 和 birth 属性,怎么办? 在 ...
- python之使用__future__(解决版本不同,不兼容问题)
Python的新版本会引入新的功能,但是,实际上这些功能在上一个老版本中就已经存在了.要“试用”某一新的特性,就可以通过导入__future__模块的某些功能来实现. 例如,Python 2.7的整数 ...
- iOS面试必备-iOS基础知识
近期为准备找工作面试,在网络上搜集了这些题,以备面试之用. 插一条广告:本人求职,2016级应届毕业生,有开发经验.可独立开发,低薪求职.QQ:895193543 1.简述OC中内存管理机制. 答:内 ...
- LeetCode——Construct Binary Tree from Preorder and Inorder Traversal
Question Given preorder and inorder traversal of a tree, construct the binary tree. Note: You may as ...
- 创建表空间及用户的SQL
--创建表SOFA空间: CREATE SMALLFILE TABLESPACE "SOFA" DATAFILE 'G:\oracle\product\10.2.0\ORADATA ...
- windows 10系统更新失败的解决办法
最近遇到一个问题,系统总是自动下载一个更新,看样子是个补丁吧,但是每次提醒重新启动以安装更新,但每次又安装失败,回退.就这样,下载,重启,安装失败,下载......一直循环,搞得都不敢关机了,因为这样 ...
- xenapi-add-support-for-vgpu
Model types 为了在vm中支持vgpu,问题在于vgpu是否应该被当作一个PCI设备, 虽然物理GPU不是一个SR-IOV设备,但vgpu却是以一个类似SR-IOV device上的VF赋给 ...
- Tensorflow中的命名空间scope
1.name_scope 在tensorflow中有两种声明变量的方式,tf.get_variable()和tf.Variable(). name_scope对于tf.get_variable()无效 ...
- 在线显示office文件
微信或手机浏览器在线显示office文件 1.判断浏览器类型 HttpServletRequest req = ServletActionContext.getRequest(); String us ...
- Sublime Text 3总是出现“1 missing dependency was just installed.”
Sublime Text 3总是出现“1 missing dependency was just installed.” 原因及结果 https://github.com/wbond/package_ ...