問題描述
假設“生產者”進程不斷向共享緩衝區寫人數據(即生產數據),而“消費者”進程不斷從共享緩衝區讀出數據(即消費數據);共享緩衝區共有n個;任何時刻只能有一個進程可對共享緩衝區(臨界區)進行操作。所有生產者和消費者之間要協調,以完成對共享緩衝區的操作。
分析
- 我們可把共享緩衝區中的n個緩衝塊視爲共享資源,生產者寫入數據的緩衝塊成爲消費者可用資源,而消費者讀出數據後的緩衝塊 成爲生產者的可用資源。爲此,可設置三個信號量:full、empty和mutex。其中:full表示有數據的緩衝塊數目,初值是0;empty表示無數據的緩衝塊數初值是n;mutex用於訪問緩衝區時的互斥,初值是1。實際上,full和empty間存在如下關係:full+ empty = N
- 生產者能夠生產的前提,就是empty 不爲0,當empty爲0當然就代表現在不需要生產者出現,只需要消費者盡情數據即可。so 生產者能夠進入臨界區的前提當然是empty不爲0
- 而釋放信號量以及對full 變量的控制的順序也不能調換,假設我們調換了,v(full)後發現full 還是小於0,此時會喚醒等待的消費進程,而無法釋放消費進程所需的mutex
代碼
buffer: array [0..k-1]of integer;//共享緩衝區的大小
in,out: 0..k-1;//in記錄第一個空緩衝區,out記錄第一個不空的緩衝區
empty,full,mutex: semaphore;
//empty:無數據的緩衝塊,控制緩衝區不滿
// full:有數據的緩衝塊控制緩衝區不空
// mutex保護臨界區
//初始化
empty=k,full=0,mutex=1
cobegin
procedure producer: procedure consumer:
while true then while true then
begin begin
produce(&item); p(full);
p(empty); p(mutex);
p(mutex); item:=buffer[out];
out:=(out+1)mod k;
buffer[in]:=item; v(mutex);
in:=(in+1) mod k; v(empty);
v(mutex); consume(&item);
v(full); end
end
coend