生產者與消費者問題

在學習進程互斥中,有個著名的問題:生產者-消費者問題。這個問題是一個標準的、著名的同時性編程問題的集合:一個有限緩衝區和兩類線程,它們是生產者和消費者,生產者把產品放入緩衝區,相反消費者便是從緩衝區中拿走產品。

生產者在緩衝區滿時必須等待,直到緩衝區有空間才繼續生產。消費者在緩衝區空時必須等待,直到緩衝區中有產品才能繼續讀取。

在這個問題上主要考慮的是:緩衝區滿或緩衝區空以及競爭條件(race condition)。以下是一個含競爭條件的生產者-消費者問題實例。

#define N 100 /*number of slots in the buffer*/

int count=0; /*number of items in the buffer*/

void producer(void) {

int item;

while(TRUE) {

produce_item(&item);

if (count==N) sleep();

enter_item(item);

count=count+1;

if (count==1) wakeup(consumer);

}

}

void comsumer(void) {

int item;

while(TRUE) {

if(count==0) sleep();

remove_item(&item);

count=count-1;

if (count==N-1) wakeup(producer);

consume_item(item);

}

}

在這個實例中,首先定義了一個大小爲100的公共緩衝區,也就是臨界資源,然後的count便是緩衝區中產品的數目,初始化爲0。producer函數是生產者函數,produce_item(&item);是指生產者生產出來一個產品,但是這時候並沒有對緩衝區進行操作。而if (count==N) sleep();是測試語句,如果生產出來的產品數和緩衝區大小相等時,生產者就進入睡眠狀態。如果不等,產品就放入緩衝區內,並且產品數增加1。if (count==1) wakeup(consumer);這條語句看上去讓人十分費解,其實它的意思是,如果上一次操作時產品的數目爲0,消費者已經進入了睡眠狀態,而現在生產者又生產出來一個產品,緩衝區內不爲空,這時把消費者喚醒。消費者函數也是同樣的道理,只不過一個是取,另一個是放。

我們可以看到,這裏存在潛在的競爭條件,所謂競爭條件就是這樣一種情況:多個線程對數據產生的作用要依賴於線程的調度順序的。當兩個線程競相訪問同一數據時,就會發生競爭條件。由於時間片的原因,一個線程可以在任意一個時刻打斷其他線程,因此數據可能會被破壞或者被錯誤地解釋。在這個實例上反應的結果是,生產者和消費者兩個進程都永遠睡眠。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章