生产者--消费者题型
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
生产者--消费者题型
三、生产者—消费者题型
生产者---消费者题型在各类考试(考研、程序员证书、程序员面试笔试、期末考试)很常见,原因之一是生产者---消费者题型在实际的并发程序(多进程、多线程)设计中很常见;之二是这种题型综合性较好,涉及进程合作、互斥,有时还涉及死锁的避免。生产者---消费者题型可以全面考核你对并发程序的理解和设计能力。
生产者---消费者题型最基本的是有界缓冲区的生产者
---消费者问题和无界缓冲区的生产者---消费者问题,对这两个问题的解我们应该背下来,就像我们念高中时背一些题型一样。
1 有界缓冲区生产者-消费者问题的解前面的课程已多次讲过。假设缓冲区是无界的,试用信号灯与 PV 操作给出解法。
答:由于是无界缓冲区,所以生产者不会因得不到缓冲区而被阻塞。所以只需在前面的有界缓冲区解中去掉信号量empty及有关的PV操作即可。
2. 设有一个可以装A,B两种物品的仓库,其容量无限大,但要求仓库中A,B两种物品的数量满足下述不等式:-M≤A物品的数量-B物品的数量≤N,
其中M和N为正整数。
试用信号灯和PV操作描述A, B两种物品的入库过程。
(这是北大1991年研究生入学试题,原题不允许使用
条件表达式,解法1虽正确,但不符合原题要求)
解1:不等式 -M≤A物品的数量-B物品的数量≤N 意味着:
A物品的数量-B物品的数量≤N
B物品的数量-A物品的数量≤M
为防止缓冲区存入物品可能发生共享变量错误,A、
B入库时需要互斥。
解法1
ItemType *buffer; //仓库空间
semaphore mutex=1;
解法1借助条件表达式,用简单的互斥解题,与生产者----消费者题型毫无关系。
解法2:不使用条件表达式的解法。对于下面表达式
A物品的数量-B物品的数量≤N
B物品的数量-A物品的数量≤M
可以这样理解:
(1)若只放A而不放B,则A最多放N次便被阻塞,即假定有一个初值为N的信号量S1,A进程每操作一次就相当将信号量S1减1。当S<0时,A不能再放,此时每放入
一个B(相当于B消费了一件产品),可令S1的信号量加1,此时A有再放的机会。此时A是生产者B是消费者。(2)对B同理。即假定有一个初值为M的信号量S2。。。此时B是生产者A是消费者。
用这种解题思路,这道题就可归类于生产者----消费者问题。下面我们用思路(1)解这道题。
可以认为有一个有界缓冲区,大小为abs(N-M),
A是生产者,缓冲区下界是M,其信号量S1=M
B是消费者,缓冲区上界是N,其信号量S2=N
下面是生产者进程A
ItemType *buffer;
semaphore s1=N, s2=M, mutex=1;
void putA {
while(1){
P(s1) //生产一件A
P(mutex);
*buffer=A;
buffer++;
V(mutex);
V(s2) //通知B进程
}
}
下面是消费者进程B
void putB {
while(1){
P(s2) //生产一件B
P(mutex);
*buffer=B;
buffer++;
V(mutex);
V(s1) //通知A进程
}
}
对这道题,我是从生产者----消费者题型来理解的,同学们可能有不同思路。这道题的解与生产者----消费者标准解法的差别在于信号量初值的设定上。
后面这个解,把信号量mutex和buffer++去掉也可以,因为这个题只要主要考点不在于互斥。
3. 设自行车生产线上有一只箱子,其中有 N 个位置( N ≥ 3),每个位置可存放一个车架或一个车轮; 又设有三个工人,其活动分别为:
工人 1活动:
do {
加工一个车架 ; 车架放入箱中 ; } while (1) 工人 2活动:
do {
加工一个车轮 ;
车轮放入箱中 ;
} while (1)
工人 3活动:
do {
箱中取一个车架 ;
箱中取二个车轮 ;
组装为一台车 ;
} while (1)
试分别用信号灯与 PV 操作实现三个工人的合作,要求解中不含死锁。
这是三进程同步问题,属于生产者-消费者题型。
首先不考虑死锁问题,显然工人 1与工人3、工人2与工人3构成生产者与消费者关系,这两对生产/消费关系通过共同的缓冲区相联系。从资源的角度来看,箱子中的空位置相当于工人1和工人2的资源,而车架和车轮相当于工人3的资源。定义三个信号灯如下:
semaphore empty=N;
semaphore wheel=0;
semaphore frame=0;
三位工人的活动分别为:
工人1活动:do {
加工一个车架; P(empty);
车架放入箱中; V(frame);
} while (1) 工人2活动:
do {
加工一个车轮;
P(empty);
车轮放入箱中;
V(wheel);
} while (1)
工人3活动:
do {
P(frame);
箱中取一车架;
V(empty);
P(wheel);
P(wheel);
箱中取二车轮;
V(empty);
V(empty);
组装为一台车;