作業系統筆記 生產者與消費者問題

2021-09-26 04:28:34 字數 2521 閱讀 1996

生產者與消費者問題是程序互斥與同步中的乙個經典例子,有關這個問題的描述如下:

現存在p個生產者和c個消費者,每個生產者一次可以向緩衝池中放入乙個產品,每個消費者可以向緩衝池中一次取出乙個產品,設緩衝池的大小為n。請設計乙個排程的策略,來保證生產者與消費者之間動作的同步與互斥。

問題中已經給出了提示,就是利用程序的互斥和同步來解決此問題。此問題中,所謂的緩衝池就是乙個臨界資源,可以用乙個大小為buf_size的陣列buffer[buf_size]來表示,生產者和消費者的動作相當於兩個程序——producer()和consumer(),兩個程序對應的函式乙個負責將緩衝池的一部分置1,另乙個負責將緩衝池的一部分置0(不妨設0位無產品,1位有產品)。

至於producer()和consumer()程序應該在執行時應該對緩衝池的哪部分進行操作,就可以使用資料結構中的迴圈佇列模型:先定義兩個指標in和out,建立生產者和消費者兩個程序前,in和out先指向陣列的首位址所在的單元,每當生產者生產乙個商品,in迴圈加1,即in=(in+1)%buf_size,out也是如此。當in=out時,表示緩衝池中沒有產品,(in+1)%buf_size==out,表示緩衝池已滿

最後再來分析其中的互斥與同步關係。緩衝池有著兩種極端情況,即緩衝池全滿或全空,全滿情況下,生產者無法再生產產品,全空情況下,消費者無法再消費產品,那麼這兩種情況下如何來限制生產者或消費者來生產或消費產品呢,很顯然就是追加兩個訊號量——full與empty,full為滿緩衝池的個數,empty為空緩衝池的個數。生產者想生產產品,先wait一下empty,後signal一下full,表示「生產者獲得了生產機會,完成了生產,緩衝池產品數加1」消費者的行為以及含義就與生產者相反

其次,再考慮producer()和consumer()兩個操作是否必須是原子操作,即操作時是否可以產生外部中斷。我們將多個函式按順序併發執行,可以發現,若p == c == 1(即生產者與消費者數量均為1)時,上述兩操作併發是不會產生混亂的,然而當p和c為多個且不相等時,有可能乙個生產者將緩衝池一部分置1後,未來得及in迴圈加一,而此時另一生產者又對這部分的緩衝池置1,從而實質上未使緩衝池產品增加,這就導致了程式的混亂,這也就衍生出了另乙個互斥問題:緩衝池一次只能供乙個消費者或生產者消費或生產實現此互斥的方法,就是追加乙個緩衝池互斥鎖——mutex,mutex設定為1,表示「有乙個機會供生產者或消費者對緩衝區進行操作」,某個程序申請到操作機會後,對mutex進行wait操作,之後再進行signal操作

本人就上述問題分析之後,寫了下面的c源**,並成功通過了測試:

pro_con.c:

#include #include #include #include sem_t			sem_mutex, sem_full, sem_empty;

int buf_size;

int in = 0;

int out = 0;

int sleeptime();

void *producer(void *argu);

void *consumer(void *argu);

int main(int argc, char **ar**)

pthread_t *thread_pro = (pthread_t*)malloc(sizeof(pthread_t)*total_pro);

pthread_t *thread_con = (pthread_t*)malloc(sizeof(pthread_t)*total_con);

sem_init(&sem_mutex, 0, 1);

sem_init(&sem_full, 0, 0);

sem_init(&sem_empty, 0, buf_size);

while(pro!=total_pro && con!=total_con)

printf("\n**********accomplish to create all thread!***********\n\n");

while(1);

return 0;

}int sleeptime() }}

void *producer(void *argu)

}void *consumer(void *argu)

}

有關生產者與消費者問題的偽**在各個版本的作業系統教科書上都有,在這裡,本人對**的可實用性進行了擴充套件,使得實現的過程更接近真實情形。

簡要地說明一下上述源**的邏輯:

上述程式可在linux和windows兩個系統上執行。在linux環境下,程式的編譯和執行命令為:

gcc pro_con.c -lpthread -o pro_con

./pro_con

windows下直接開啟c/c++編譯軟體編譯,便可生成.exe檔案,執行此檔案即可。

程式執行結果演示:

作業系統,生產者 消費者問題詳解

生產者 消費者問題 分析問題,確定臨界區 設定互斥訊號量,初值為1 臨界區之前對訊號量執行p操作臨界區之後對訊號量執行v操作分析問題,找出 需要實現 一前一後 的同步關係 設定同步訊號量,初始值為0 在 前操作 之後執行v操作在 後操作 之前執行p操作分析問題,畫出前驅圖,把每一對前驅關係都看成乙個...

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

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

生產者 消費者問題筆記

生產者之間是互斥的,也即同時只能有乙個生產者進行生產 消費者之間是互斥的,也即同時只能有乙個消費者進行消費 生產者消費者之間是互斥的,也即生產者消費者不能同時進行生產和消費 容器滿時,生產者進行等待 容器空是,消費者進行等待 object的synchronized wait notifyall 實現...