生产者-消费者问题

所谓生产者-消费者问题实际上就是有一个缓冲区,生产者生产好了放进去,消费者可以从缓冲区中取出来产品用,但是需要注意的是肯定是要保证各进程都是互斥的,生产者和消费者要互斥不用多说,假设现在有两个生产者想要把产品放进缓冲区,如果都想放在同一个地方怎么办,因此一定要保证互斥性,那互斥的初始信号量是1,因此我们要设置一个互斥信号量 semaphore mutex = 1;

假设初始的缓冲区是大小为n的空缓冲区;

首先当缓冲区满了,就不能让生产者在把产品放进去了,得等消费者取出产品释放空间了才行,也就是说在缓冲区满这种情况,必须是消费者在生产者之前,那这就是要有一个同步,同步信号量就是空闲缓冲区的大小,就是要确认一下空闲缓冲区有没有位置,空闲缓冲区的初始值就是n ,semaphore empty = n;

当缓冲区是空的时候,同样不能让消费者从中取出产品,那这里就是生产者要在消费者之前执行,那这里也是一个同步关系,这里的同步信号量就是产品数量,初始值为0,semaphore full = 0;;

直观点看就是下面这张图

同步

下面上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
semaphore mutex = 1;
semaphore full = 0;
semaphore empty = n;
producer(){
while(1){
生产一个产品;
P(empty);//1
P(mutex);//2
把产品放进缓冲区;
V(mutex);
V(full);
}
}

consumer(){
while(1){
P(full);//3
P(mutex);//4
从缓冲区取走一个产品;
V(mutex);
V(empty);
使用产品;“
}
}

需要仔细理解一下full和empty,注意full缓冲区里的产品数,empty是缓冲区空闲的大小,而且敲重点同步信号量定的是初始值!!!不要想当然。还有就是要注意实现互斥的P操作一定要写在实现同步的P操作之后,V操作无所谓先后,为什么呢?如果颠倒了位置(2143),假设缓冲区已经满了,即empty为0,full为n,如果先执行互斥的P操作,mutex为0,再执行P(empty),因为已经没有空闲缓存区了,因此生产者被阻塞,切回消费者,因为mutex已经为0了,消费者这边P(mutex)也走不下去了,消费者也则色,这就造成了消费者等生产者释放临界区,生产者等待消费者释放空闲缓冲区,生产者和消费者循环等待被对方唤醒,形成死锁,同样的若缓冲区为空,也会造成死锁.

还有就是尽量不要把”生产一个产品”和”使用产品”放在缓冲区那步代码,最好像上面那么些,不然占用资源会造成忙等。

-------------本文结束感谢您的阅读-------------