-
Notifications
You must be signed in to change notification settings - Fork 1
8月14日笔记
14.2 信号量使用
2种信号量:1、二进制信号量:资源数目为0或1;2、资源信号量:资源数目为任何非负值
使用:1、互斥访问:临界区的互斥访问控制;2、条件同步:线程间的事件等待
1、临界区的互斥访问控制
每类资源设置一个信号量,其初值为1,P、V操作必须成对出现,P操作保证互斥访问临界资源,V操作在使用后释放临界资源;PV操作不能次序错误、重复或遗漏
2、信号量实现条件同步
条件同步设置一个信号量,其初值为0
生产者-消费者问题
一个或多个生产者在生成数据后放在一个缓冲区里,单个消费者从缓冲区取出数据处理,任何时刻只能有一个生产者或消费者可访问缓冲区
问题分析:
1、任何时刻只能有一个线程操作缓冲区 (互斥访问)
2、缓冲区空时,消费者必须等待生产者 (条件同步)
3、缓冲区满时,生产者必须等待消费者 (条件同步)
14.3 管程(Moniter):并发程序的编程方法
管程是解决在处理临界区时的一些麻烦
为了支持管程,需要在高层抽象中增加一个条件变量
管程是一种用于多线程互斥访问共享资源的程序结构,采用面向对象方法,简化了线程间的同步控制,保证了任何时刻最多只有一个线程执行管程代码
与临界区的区别:正在管程中的线程可临时放弃管程的互斥访问,等待事件出现时恢复
管程的使用:在对象/模块中,收集相关共享数据;定义访问共享数据的方法
管程的组成:一个锁(控制管程代码的互斥访问);0个或多个条件变量,管理共享数据的并发访问,如果是0个,就等同于一个临界区,如果是其中有一个以上的条件变量,就是管程所特有的,用来管理共享数据的并发访问,
条件变量是管程内的等待机制,进入管程的线程因资源被占用而进入等待状态;每个条件变量表示一种等待原因,对应一个等待队列
Wait()操作:将自己阻塞在等待队列中,唤醒一个等待者或释放管程的互斥访问
Signal()操作:将等待队列中的一个线程唤醒,如果等待队列为空,则等同空操作
管程中的条件变量是内部的线程优先执行,还是正占用管程处于执行状态的线程更有优先权来执行呢?两种不同的处理办法,对应两种不同的管程,Hansen管程、Hoare管程
Hansen管程:当前执行的线程更优先,少一次切换,效率更高,主要用于真实OS和Java中
Hoare管程:内部线程优先执行,更合理,更容易证明它的确定性,更多用于教科书中
Hansen管程:while,条件变量释仅是一个提示,需要重新检查条件,高效
Hoare管程:if,条件变量释放同时表示放弃管程访问,释放后条件变量的状态可用,低效
14.4 哲学家就餐问题
14.5 读者-写者问题
共享数据的两类使用者
读者:只读取数据,不修改
写着:读取和修改数据
读者-写者问题描述:对共享数据的读写
读-读允许:同一时刻,允许有多个读者同时读
读-写互斥:没有写者时读者才能读;没有读者时写者才能写
写-写互斥:没有其他写者时写者才能写
优先策略:
读者优先策略:只要有读者正在读状态,后来的读者都能直接进入;如读者持续不断进入,则写者就处于饥饿
写着优先策略:只要有写者就绪,写者应尽快执行写操作;如写者持续不断就绪,则读者就处于饥饿