生產者消費者續

2021-06-16 23:56:07 字數 3148 閱讀 4246

生產者-消費者問題詳解

2009-11-30 22:07:03

分類:

要理解生產消費者問題,首先應弄清

pv操作的含義:pv

操作是由

p操作原語和

v操作原語組成(原語是不可中斷的過程),對訊號量進行操作,具體定義如下:

p(s):①將訊號量

s的值減1,即

s=s-1;

②如果s³0

,則該程序繼續執行;否則該程序置為等待狀態,排入等待佇列。

v(s):①將訊號量

s的值加1,即

s=s+1;

②如果s>0

,則該程序繼續執行;否則釋放佇列中第乙個等待訊號量的程序。

這只是書本的定義,對於這部分內容,老師先不要急於解釋上面的程式流程,而是應該讓學生首先知道

p操作與

v操作到底有什麼作用。

p操作相當於申請資源,而

v操作相當於釋放資源。所以要學生記住以下幾個關鍵字:

p操作-----

à申請資源

v操作----

à釋放資源

為此舉兩個生活中的例子:

例一:在公共**廳打**

公共**廳裡有多個**,如某人要打**,首先要進行申請,看是否有**空閒,若有,則可以使用**,如果**亭裡所有**都有人正在使用,那後來的人只有排隊等候。當某人用完**後,則有空**騰出,正在排隊的第乙個人就可以使用**。這就相當於

pv操作:

某人要打**,首先要進行申請,相當於執行一次

p操作,申請乙個可用資源(**);

某人用完**,則有空**騰出,相當於執行一次

v操作,釋放乙個可用資源(**)。

在多**課件中,這部分內容充分通過動畫效果,演示整個申請**資源(

p操作)與釋放**資源(

v操作)的過程,同時顯示當前可用的資源個數(**個數)。課件直觀生動,一目了然,學生非常容易接受,並且理解深刻。

在理解了

pv操作的的含義後,就必須講解利用

pv操作可以實現程序的兩種情況:互斥和同步。根據互斥和同步不同的特點,就有利用pv

操作實現互斥與同步相對固定的結構模式。這裡就不詳細講解了。但生產者

-消費者問題是乙個有代表性的程序同步問題,要學生透徹理解並不容易。但是如果我們將問題細分成三種情況進行講解,理解難度將大大降低。

1

)乙個生產者,乙個消費者,公用乙個緩衝區。

可以作以下比喻:將乙個生產者比喻為乙個生產廠家,如伊利牛奶廠家,而乙個消費者,比喻是學生小明,而乙個緩衝區則比喻成一間好又多。第一種情況,可以理解成伊利牛奶生產廠家生產一盒牛奶,把它放在好又多一分店進行銷售,而小明則可以從那裡買到這盒牛奶。只有當廠家把牛奶放在商店裡面後,小明才可以從商店裡買到牛奶。所以很明顯這是最簡單的同步問題。

解題如下:

定義兩個同步訊號量:

empty

——表示緩衝區是否為空,初值為1。

full

——表示緩衝區中是否為滿,初值為0。

生產者程序

while(true)

消費者程序

while(true)

消費者程序

while(true)

3

)一組生產者,一組消費者,公用

n個環形緩衝區

第三種情況,可以理解成有多間牛奶生產廠家,如蒙牛,達能,光明等,消費者也不只小明一人,有許許多多消費者。不同的牛奶生產廠家生產的商品可以放在不同的好又多分店中銷售,而不同的消費者可以去不同的分店中購買。當某一分店已放滿某個廠家的商品時,下乙個廠家只能把商品放在下一間分店。所以在這種情況中,生產者與消費者存在同步關係,而且各個生產者之間、各個消費者之間存在互斥關係,

他們必須互斥地訪問緩衝區。

解題如下:

定義四個訊號量:

empty

——表示緩衝區是否為空,初值為n。

full

——表示緩衝區中是否為滿,初值為0。

mutex1

——生產者之間的互斥訊號量,初值為1。

mutex2

——消費者之間的互斥訊號量,初值為1。

設緩衝區的編號為1~

n-1,定義兩個指標in和

out,分別是生產者程序和消費者程序使用的指標,指向下乙個可用的緩衝區。

生產者程序

while(true)

消費者程序

while(true); // 緩衝初始化為0, 開始時沒有產品

sem_t empty_sem; // 同步訊號量, 當滿了時阻止生產者放產品

sem_t full_sem;   // 同步訊號量, 當沒產品時阻止消費者消費

pthread_mutex_t mutex; // 互斥訊號量, 一次只有乙個執行緒訪問緩衝

int product_id = 0;   //生產者id

int prochase_id = 0; //消費者id

/* 列印緩衝情況 */

void print()

/* 生產者方法 */

void *product()

}/* 消費者方法 */

void *prochase()}

int main()

//初始化互斥訊號量

int ini3 = pthread_mutex_init(&mutex, null);

if(ini3 != 0)

// 建立n個生產者執行緒

ret= pthread_create(&id1, null, product, (void *)(&i));

if(ret != 0)

//建立n個消費者執行緒

ret= pthread_create(&id2, null, prochase, null);

if(ret != 0)

//銷毀執行緒

pthread_join(id1,null);

pthread_join(id2,null);

exit(0); }

生產者消費者 生產者與消費者模式

一 什麼是生產者與消費者模式 其實生產者與消費者模式就是乙個多執行緒併發協作的模式,在這個模式中呢,一部分執行緒被用於去生產資料,另一部分執行緒去處理資料,於是便有了形象的生產者與消費者了。而為了更好的優化生產者與消費者的關係,便設立乙個緩衝區,也就相當於乙個資料倉儲,當生產者生產資料時鎖住倉庫,不...

生產者消費者

using system using system.collections.generic using system.threading namespace gmservice foreach thread thread in producers q.exit console.read public...

生產者消費者

執行緒通訊 乙個執行緒完成了自己的任務時,要通知另外乙個執行緒去完成另外乙個任務.wait 等待 如果執行緒執行了wait方法,那麼該執行緒會進入等待的狀態,等待狀態下的執行緒必須要被其他執行緒呼叫notify方法才能喚醒。notify 喚醒 喚醒執行緒池等待執行緒其中的乙個。notifyall 喚...