天天看點

生産者消費者 & 讀者寫者

生産者消費者 & 讀者寫者

生産者消費者

生産者消費者 & 讀者寫者

對于生産者消費者這個問題,我們可以用生活中一個簡單的例子來說明:

桌子上有個盤子,一個人往盤子裡面放蘋果,一個人從盤子裡面拿走蘋果,放蘋果的人相當于生産者,拿走蘋果的人相當于消費者,而盤子就相當于一個生産場所。如果我們要保證拿蘋果的人一直都有蘋果拿,那就要讓放蘋果的人一直放,而且要比拿蘋果的人快一點。當盤子滿的時候放蘋果的人就要等着拿蘋果的人把蘋果拿走,等盤子裡有了位置,就可以繼續放蘋果。如果我們要求每次隻能放一個蘋果,拿蘋果的人每次也隻能拿一個蘋果,而放蘋果和拿蘋果的人都不隻是一個人,這樣的話,放蘋果的人和放蘋果的人之間就會産生互斥關系,一個人放蘋果的時候,其他人就不能放,拿蘋果的人也是一樣,一個人拿蘋果的時候,其他人就不能拿。而拿蘋果的人和放蘋果的人也有互斥關系和同步關系,放蘋果的人放了蘋果之後,要通知拿蘋果的人來拿蘋果,否則盤子滿了,放蘋果的人就要等待。

生産者消費者 & 讀者寫者

滿

生産者消費者 & 讀者寫者

生産者消費者 & 讀者寫者

生産者消費者 & 讀者寫者

生産者消費者 & 讀者寫者

生産者消費者 & 讀者寫者

生産者消費者 & 讀者寫者

生産者消費者 & 讀者寫者

生産者消費者 & 讀者寫者

生産者消費者 & 讀者寫者

生産者消費者 & 讀者寫者

生産者消費者 & 讀者寫者

生産者消費者 & 讀者寫者
生産者消費者 & 讀者寫者

好了,不說蘋果了,我們來官方一點啦

生産者要做的就是生産資料,消費者要做的是讀取資料并且要拿走。而且生産者和消費者是在一個環形緩沖區進行的,和我在管道那篇部落格中寫的一樣

生産者消費者 & 讀者寫者

生産者消費者之間的關系

(1)消費者和消費者是互斥關系,因為一個消費者來讀取資料的時候其他消費者是不能來讀取資料的 (2)生産者和生産者是互斥關系,因為一個生産者在寫入資料的時候其他生産者是不能寫入資料的 (3)生産者和消費者是互斥關系,同步關系,當生産者生産了之後,會通知消費者來消費,否則當生産者生産滿了的時候,就需要等待消費者來消費,等到滿足生産的要求的時候再生産,這就對于臨界資源的通路會産生一定的順序,會提高系統内部資源的讀取速度。

消費者指向的位置都是有有效資料的,生産者指向的位置都是沒有有效資料的,和管道的環形緩沖區類似,把管道的環形緩沖區圖拿過來湊合看看了解吧。 這幅圖裡面,你可以把write看作是生産者,在一直生産資料,read可以看作是消費者,一直在讀取資料。 生産者所關心的資源是環形buf中空餘的位置,即沒有有效資料的位置, 消費者不關心格子,隻關心資料

生産者消費者 & 讀者寫者
生産者消費者 & 讀者寫者

讀者寫者問題

生産者消費者 & 讀者寫者

讀者寫者都幹什麼呢?    寫者把資料扔到緩沖區中,讀者隻讀資料,不會把資料拿走

生産者消費者 & 讀者寫者

讀者寫者的關系: (1)讀者和讀者沒有關系,因為資料不會被拿走,不會發生争奪資源的問題,是以誰都可以讀到相同的資料, (2)寫者和寫者是互斥關系,一個寫的時候其他寫者就不能寫 (3)讀者和寫者是互斥關系,同步關系,類似生産者和消費者

生産者消費者 & 讀者寫者

讀者寫者會出現的問題: (1)讀者很多,寫者隻有一個的時候,讀者會不斷的來讀資料,寫者沒機會寫如資料,則會出現寫者饑餓 (2)寫者很多,讀者隻有一個的時候,寫者會不斷的寫入資料,讀者沒機會寫入資料,則會出現讀者饑餓

生産者消費者 & 讀者寫者

針對寫者饑餓和讀者饑餓的解決方法:

(1)寫者優先:當有很多讀者的時候,當寫者來的時候,後續來的讀者就不能讀了,等目前正在讀的讀者讀完,然後讓寫者先寫,其他讀者不能進行讀取 (2)讀者優先:當有很多寫者,來了一個讀者的時候,當目前寫者寫完的時候讓讀者先讀,讀完了再讓其他的寫者寫

生産者消費者 & 讀者寫者

關于讀寫鎖: (1)以隻讀方式加鎖,是讀者的行為,當有寫者的時候,寫者不會進行寫操作,寫者檢測到讀者有讀鎖的時候(Pthread_rwlock_tryrdlock(&rwlock)!=0) 會等待,直到讀者不再讀,如果沒有檢測到隻讀鎖(Pthread_rwlock_tryrdlock(&rwlock)==0),則會直接寫入 (2)其他鎖是基于挂起,當申請鎖的時候申請不到就會被挂起等待其他程序釋放鎖 (3)讀寫鎖是基于自旋鎖,申請鎖資源,如果鎖資源就緒,就會立即被占用,如果鎖資源沒有就緒,則會一直自旋申請

自旋鎖:當申請資源的時候不會被挂起,節省了挂起和喚醒的代價

如果在臨界資源裡逗留的時間很長,則需要使用互斥鎖或者信号量