管程monitor
进程间通信
典型操作系统的IPC机制
管程monitor:
为什么出现管程?
问题:信号量机制的不足--程序编写困难,易出现死锁
管程的定义:
1,一个特殊的模块
2,是一个名字
3,由关于共享资源的数据结构及在其上操作的一组过程组成
进程和管程的关系:
进程只能通过调用管程中的过程来间接地访问管程中的数据结构。
作为一种同步机制,管程要解决的两个问题:
1,互斥
管程时互斥进入的
---为了保证管程中数据结构的数据完成性
管程的互斥性是由编译器负责保证的
2,同步
设置了条件变量及等待/唤醒操作以解决同步问题
可以让一个进程或线程在条件变量上等待(此时,应先释放管程的使用权),也可以听过发送信号将等待在条件变量
上的进程或线程唤醒
遇到的问题:
是否会出现这样一种场景,有多个进程同时在管程中出现
解决方法:
1,P等待Q执行
2,Q等待P继续执行
3,规定唤醒操作为管程中最后一个可执行操作
HORAE管程示意图:
说明:
因为管程时互斥进入的,所以当一个进程试图进入一个已被占用的管程时,应当在管程的入口处等待
为此,管程的入口处设置一个进程等待队列,称作入口等待队列
如果进程P唤醒进程Q,则P等待Q执行;如果进程Q执行中又唤醒进程R,则Q等待R执行......,如此,在管程内部可能会出现多个等待
进程
在管程内需要设置一个进程等待队列,称为紧急等待队列,紧急等待队列的优先级高于入口等待队列的优先级
HOARE管程---条件变量的实现
条件变量:在管程内部说明和和使用的一种特殊类型的变量
var c:condition
对于条件变量,可以执行wait和signal操作
wait(c):
如果紧急等待队列为非空,则唤醒(紧急等待队列)第一个等待者,否则释放管程的互斥权,执行此操作的进程进入c(条件变量链)链末尾
signal(c):
如果c链为空,则相当于空操作,执行此操作的进程继续执行;否则唤醒第一个等待者,执行此操作的进程进入
紧急等待队列的末尾
管程的应用:
管程实现的两个途径
1,直接构造---效率高
2,间接构造
---用某种已经实现的同步机制去构造。eg:信号量,p,v
用管程解决生产者消费者问题:
//管程:
MESA管程:Mesa语言
Hoare管程一个缺点
两次额外的进程切换
解决:
signal-->notify
notify:当一个正在管程中的进程执行notify(x)时,它使得x条件队列得到通知,发信号的进程继续执行
注意问题:
1,notify的结果:位于条件队列头的进程在将来合适的时候且当处理器可用时恢复执行
2,由于不能保证在它之前没有其他进程进入管程,因而这个进程必须重新检查条件
--->用while循环取代if语句
3,导致对条件变量至少多一次二外的检测(但不在有额外的进程切换),并且对等待进程在notify之后
何时运行没有任何限制
改进:
1,给每个条件原语关联一个监视计时器,不论是否被通知,一个等待时间超时的进程将设为就绪态
2,当该进程被调度执行时,会再次检查相关条件,如果条件满足则继续执行
超时可以预防一下情况发生:
当某些进程在产生相关条件的信号之前失败时,等待该条件的进程就会被无限制地推迟执行而处于饥饿状态
引入BRDADCAST
broadcast:使所有在该条件上等待的进程都被释放并进入就绪队列
1,当一个进程不知道有多少进程将被**时,这种方式非常方便
2,当一个进程难以准确判定将**哪个进程时,也可以使用广播
管程小结:
PTHREAD中同步机制
互斥量--保护临界区
条件变量--解决同步
解决生产者消费者问题:
pthread_cond_wait:执行三个动作:若条件不成立
1,解锁
2,等待--等待条件变量
当收到一个解锁等待的信号(pthread_cond_signal或pthread_cond_broad_cast)之后,pthread_cond_wait马上需要做的动作:
3,上锁(被唤醒的第一件事)
为什么需要通讯机制?
1,信号量及管程的不足
2,不适用于多处理器的情况
---->进程通信机制
1,消息传递
send & receive原语
适用于:分布式系统、基于共享内存的多处理机系统、单处理机系统
可以解决进程间的同步问题,通信问题
基本通信方式:
消息传递
共享内存
管道
套接字
远程过程调用
消息传递:
用P,V操作实现send原语:
共享内存:
管道通信PIPE
利用一个缓冲传输介质---内存或文件连接两个相互通信的进程
1,字符流方式写入读出
2,先进先出顺序
3,管道通信机制必须提供的协调能力
互斥、同步、判断对方进程是否存在
进程同步/通信实例:
LINUX的进程通信机制:
原子操作:
1,不可分割,在执行完之前不会被其他任务或和事件中断
2,常用于实现资源的引用计数
3,atomic_t
例子:
atomic_t v = atomic_init(0);
atomic_set(&v,4);
atmoc_add(2,&v);
atomic_inc(&v);
printk("%d\n",atomic_read(&v));
int atomic_dec_and_test(atomic_t *v);
屏障(BARRIER) ---矩阵运算--迭代
1,一种同步机制(又称栅栏,关卡)
2,用于对一组线程进行协调
3,应用场景
--- 一组线程协同完成一项任务,需要所有的线程都到达一个汇合点后再一起向前推进