1. 程式人生 > >讀者寫者模型與生產者消費者模型

讀者寫者模型與生產者消費者模型

讀者寫者模型
讀者寫者訪問一塊共享的資料區域,讀者對共享資源進行讀訪問,寫者對共享記憶體進行寫操作。在多處理器系統中,運去多個讀者同時訪問共享記憶體,而寫者是排他性的,每次只能有一個寫者去寫入資料。在使用讀寫鎖時,一個讀寫鎖只能同時一個讀者和多個寫者,但不能同時既有讀者又有寫者。
公平情況的讀者寫者程式碼:
這裡寫圖片描述
這裡寫圖片描述
執行結果
這裡寫圖片描述
此時讀者和寫者有相同的機會執行,是公平情況。
讀者寫者有三類情況:讀者優先,寫者優先,公平情況
1、讀者優先
讀者先來讀取資料(其他的讀者也可以來讀取資料),此時寫者等待,也就是說讀者可以插寫者的隊,這是讀者優先的關鍵點,只有當讀者為0,寫者才能來寫入資料。
1、寫者要有一個互斥訊號量 writeMutex=1,因為寫者一次只能一個來寫資料
2、對讀者要有一個記錄數目的 int 變數,readcount=0,一個互斥訊號量readMutex = 1,保證多個讀者來的時候,能似的 readcount 互斥的變化,也就是不被混亂的計數。
2、寫者優先
類似讀者優先演算法,同理,這裡是寫者可以插隊,多用一個 readable 訊號量,控制寫者可以優先於讀者進入臨界區,一個整數 writecount 統計寫者,而 wmutex 控制寫者互質訪問 writecount
3、公平情況
讀者想進的時候,有寫者正在寫(或者正在等待寫),讀者就不能進(讀者等待),只有寫者走了,讀者才能進。和一相比,需要多一個訊號量 wmutex=1,表示是否存在寫者正在寫或者等待寫,如果存在,讀者就等待,讀者不能插隊了。
生產者消費者模型


從下圖中可以看出來生產者和消費者之間用一個類似佇列的容器來存放產品,生產者只需要關心這個倉庫,並不需要關心具體的消費者是誰,甚至都不知道這個消費者的存在。對於消費者而言他不需要關心具體的生產者,他只需要關心這個倉庫中有沒有產品。
這裡寫圖片描述
基於固定大小的環形佇列(訊號量實現)
程式碼展示
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
執行結果
這裡寫圖片描述
在程式中用訊號量來實現生產者和消費者的同步,生產者在生產產品後會進行sem_post()操作釋放資源(V操作),消費者sem_wait()獲得資源,開始向下執行,消費者在消費後會對生產者進行sem_post()操作,從而實現消費者和生產者之間的同步。
藉助連結串列實現消費者生產者模型(條件變數實現)
這裡寫圖片描述

這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
執行結果
這裡寫圖片描述
上面的程式碼展示的是多個生產者消費者模型,在產品較多時,兩個消費者均可以消費到,在只有一個產品時,消費者發生了競爭,兩個消費者均可能有機會消費到資料。程式碼中使用條件變數實現了消費者生產者之間的同步,pthread_cond_wait()函式令執行緒等待,直至其他執行緒呼叫pthread_cond_signal()喚醒某個在condition variable上等待的另一個執行緒,或者使用pthread_cond_broadcast()喚醒等待的所有執行緒,執行緒之間通過競爭來判斷哪個執行緒先執行。
讀者寫者模型和生產者消費者模型區別
讀者寫者模型中寫者寫入資料,但讀者並不會消費資料,只會訪問。其中的寫操作是排他的(排斥讀者和其他寫者),讀操作是共享的。
生產者消費者模型中生產者生產產品,消費者不斷的消費產品,產品的數量在不斷的下降。如果此時臨界區無資料時,消費者被阻塞,直至生產者生產出資料時來喚醒消費者,若臨界區資源滿了時,生產者被阻塞,在消費者消費後喚醒生產者。(待完善)