信号量同步互斥问题
一、信号量
信号量是一种抽象数据类型
- 由一个整型(sem)变量和两个原子操作组成
- P():sem减1,如果sem<0进入等待状态,否则继续
- V():sem加1,如果sem<=0则唤醒一个等待的线程
二、管程
管程是一种用于多线程互斥访问共享资源的程序结构
- 局部数据变量只能被管程的过程访问,任何外部过程都不能访问
- 一个进程通过调用管程的一个过程进入管程
- 在任何时候,只能有一个进程在管程中执行,调用管程的任何其他进程都被阻塞,以等待管程可用
管程的使用
- 管理共享数据
- 定义访问共享数据的方法
条件变量
- 条件变量是管程内的等待机制
1.1. 进入管程的线程因资源被占用而进入等待状态
1.2. 每个条件变量表示一种等待原因,对应一个等待队列 - Wait()操作
2.1. 将自己阻塞在等待队列中
2.2. 放弃对管程的互斥访问权限(同一时刻管程只能有一个进程访问) - Signal()操作
3.1. 将等待队列中的一个线程唤醒(信号量机制中的Signal是释放一个信号量,如果信号量≤0则唤醒一个线程)
三、生产者消费者问题
①生产者在生成数据后放在一个缓冲区里
②消费者从缓冲区中读取数据
③任何时刻只能有一个生产者或消费者可以访问缓冲区
问题分析:
①任何时刻只能有一个线程操作缓冲区
②缓冲区满时,生产者要等待消费者
③缓冲区空时,消费者要等待生产者
利用信号量解决
利用管程解决
四、哲学家就餐问题
问题描述
解决方案
五、读者-写者问题
管程的状态变量
- AR:正在读的读者数量
- AW:正在写的写者数量
- WR:等待读的读者数量
- WW:等待写的写者数量
- okToRead:读者的等待队列
- okToWrite:写者的等待队列
读者模块(写者优先)
startRead():如果有写者正在写或等待写,则进入等待队列
DoneRead():如果没有读者在读且有写者等待写,则唤醒写者
写者模块(写者优先)
StartWrite():如果有读者在读或有写者在写,则进入等待队列
DoneWrite():如果有写者等待写,则优先唤醒写者,或者唤醒等待的读者