Skip to content

经典问题

生产者-消费者问题

  • 一个互斥量(访问临界资源需要互斥访问)
  • 两个同步量,产品数和空缓冲区的数量(可能是生产等消费,也可能是消费等生成)

实现互斥的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);
    }
}

哲学家进餐问题

重点在于防止死锁,有三种方法:

  • 限制最多同时进餐数量
  • 奇偶拿筷子顺序相反
  • 先检查左右筷子是否都可用

当然我们也可以直接在去筷子的时候多加上一个互斥锁,这样最多只有一个人被阻塞,也不会死锁