生產者與消費者問題是程序互斥與同步中的乙個經典例子,有關這個問題的描述如下:
現存在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 實現...