天天看點

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

讀者寫者模型

讀者寫者通路一塊共享的資料區域,讀者對共享資源進行讀通路,寫者對共享記憶體進行寫操作。在多處理器系統中,運去多個讀者同時通路共享記憶體,而寫者是排他性的,每次隻能有一個寫者去寫入資料。在使用讀寫鎖時,一個讀寫鎖隻能同時一個讀者和多個寫者,但不能同時既有讀者又有寫者。

公平情況的讀者寫者代碼:

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

運作結果

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

此時讀者和寫者有相同的機會運作,是公平情況。

讀者寫者有三類情況:讀者優先,寫者優先,公平情況

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()喚醒等待的所有線程,線程之間通過競争來判斷哪個線程先運作。

讀者寫者模型和生産者消費者模型差別

讀者寫者模型中寫者寫入資料,但讀者并不會消費資料,隻會通路。其中的寫操作是排他的(排斥讀者和其他寫者),讀操作是共享的。

生産者消費者模型中生産者生産産品,消費者不斷的消費産品,産品的數量在不斷的下降。如果此時臨界區無資料時,消費者被阻塞,直至生産者生産出資料時來喚醒消費者,若臨界區資源滿了時,生産者被阻塞,在消費者消費後喚醒生産者。(待完善)

繼續閱讀