3. 生产者-消费者问题
用一个数组表示具有n个缓冲区的缓冲池;用输入指针in,指示下一个可投放消息的缓冲区;用输出指针out,指示下一个可获取消息的缓冲区,利用记录型信号量解决资源使用问题。
3. 【解析】本题可用PV操作“五步曲”来解答,解题过程如下:
第一步:找进程
l 生产者
l 消费者
第二步:找操作
(1). 生产者
l 生产一个数据
l 将数据放入in指针指向的缓冲区
(2). 消费者
(3). 从out指针指向的缓冲区读取数据
(4). 消费数据
第三步:找关系
l 只有缓冲区有空闲,生产者才能将生产的数据放入(空闲)缓冲区中。
l 只有缓冲区有数据,消费者才能取数据(来消费)。
第四步:找初值
l n个缓冲区,可用信号量empty表示,初值为全部为空,即为n。此时生产者可以有n个空闲的缓冲区用来存放数据,消费者初始状态下没有直接消费的数据,需等待。
l 设full表示当前已经被生产者生产和放入数据的缓冲区数量,初始值为0。
l 缓冲区必须互斥访问,所以,设置互斥信号量mutex,初值为1。
l 用一个数组buffer,用来表示缓冲区。
l 两个指针in和out,in指针指向生产者可以直接存放生产数据的缓冲区,out指针指向消费者可以直接消费生产者生产好的数据的缓冲区。
【注意】buffer数组是用来表示缓冲区的,而empty和full是用来表示缓冲区的空闲和使用情况的,这二者不一样,请读者仔细体会。
第五步:写算法
PV算法如下:
Var mutex, empty,full:semaphore∶=1, n, 0; //三个信号量
buffer:array[0, …, n-1] of item; //n个缓冲区
in, out: integer:=0, 0; //生产者和消费者指针
begin
parbegin
生产者进程:
begin
repeat
…
produce an item nextp; //生产一个产品(数据)放入nextp
…
wait(empty); //看看有没有空闲的缓冲区
wait(mutex); //有空闲的缓冲区
buffer(in):=nextp; //把nextp中的产品送往buffer(in);
in:= (in+1) mod n; //in指针指向下一个位置
signal(mutex); //释放互斥信号
signal(full); //满缓冲区加1
until false;
end
消费者进程:
begin
repeat
wait(full); //消费者看看有没有满的缓冲区
wait(mutex); //有满的缓冲区
nextc:=buffer(out); //从buffer(out)中取出产品放入nextc
out:= (out+1) mod n; //out指针指向下一个位置
signal(mutex); //释放缓冲区互斥访问信号
signal(empty); //空闲缓冲区的数量加1
…
consume the item in nextc; //消费nextc中的产品
until false;
end
parend
end
转载声明:本文完全来自于http://www.kaoyanlianmeng.com,版权归梦享团队所有,为尊重版权,特此声明出处!