经典问题
生产者-消费者问题
- 一个互斥量(访问临界资源需要互斥访问)
- 两个同步量,产品数和空缓冲区的数量(可能是生产等消费,也可能是消费等生成)
实现互斥的P操作一定要在实现同步的P操作之后!(否则死锁)
同步进程一般设为与资源相关,互斥一般设为1
多生产者-多消费者问题
同样的逻辑分析同步与互斥
当缓冲区为1的时候,不要互斥量,因为同步量至多只有一个为1
吸烟者问题
重点是要保持同步操作的顺序: 先放烟后吸烟
因为显然这次的缓冲区必然为1,所以只需要在前操作之后P,后操作之前V即可(不像生产者-消费者问题)
读者-写者问题
需求:
- 写者-写者互斥
- 读者-写者互斥
但是读者像之前一样开信号量加锁,因为这样读者-读者之间就会互斥了
怎么解决呢?
开一个cnt用于维护读者数量,第一个读者负责加锁,最后一个读者负责解锁
为了防止写者饿死,我们还可以开一个信号量w,实现最原始的互斥
要注意到P(w)在reader的位置
cpp
writer(){
while(1){
P(w);
P(rw);
// todo
V(rw);
V(w);
}
}
reader(){
while(1){
P(w);
P(mutex);
if(count==0)
P(rw);
count++;
V(mutex);
V(w);
// todo
P(mutex);
count--;
if(count==0)
V(rw);
V(mutex);
}
}
哲学家进餐问题
重点在于防止死锁,有三种方法:
- 限制最多同时进餐数量
- 奇偶拿筷子顺序相反
- 先检查左右筷子是否都可用
当然我们也可以直接在去筷子的时候多加上一个互斥锁,这样最多只有一个人被阻塞,也不会死锁