1. 程式人生 > >生產者消費者 & 讀者寫者

生產者消費者 & 讀者寫者

生氣生產者消費者

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

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

驚恐滿驚恐驚恐驚恐驚恐驚恐驚恐驚恐驚恐驚恐驚恐驚恐驚恐

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

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

疑問生產者消費者之間的關係

(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)讀寫鎖是基於自旋鎖,申請鎖資源,如果鎖資源就緒,就會立即被佔用,如果鎖資源沒有就緒,則會一直自旋申請 自旋鎖:當申請資源的時候不會被掛起,節省了掛起和喚醒的代價 如果在臨界資源裡逗留的時間很長,則需要使用互斥鎖或者訊號量