問題:
系統中有一組生產者進程和一組消費者進程,生產者每次生產一個產品放入緩衝區,消費者每次從緩衝區取出一個產品並使用(注:這裏的產品可以理解成某種數據)。
條件:生產者、消費者共享一個初始化爲空的、大小爲n的緩衝區。
提示:
做這一題之前一定要熟練的掌握進程的互斥和進程的同步,一定要會!!一定要會!!一定要會!
不會的話可以 點擊這裏!!!
題目分析:
1.首先讀題之後就容易知道,咱們現在有一個緩衝區,生產者負責生產產品,然後把產品放到緩衝區裏面,生產產品的前提條件是緩衝區未滿,緩衝區的大小爲n。消費者負責使用產品,但是使用產品的前提條件緩衝區裏面有產品。
2.下面分析一下互斥和同步的問題,因爲只有一個緩衝區(生產者放產品,消費者取產品),所以這裏可以把緩衝區看成臨界資源(類似多個打印機進程打印那樣),而且多個生產者之間不能同時往緩衝區中放產品(可能會造成覆蓋),多個消費者也不可以同時在緩衝區中取產品,也不可以生產者放產品的同時,消費者取產品。
經過上面的分析,可以得出進程的互斥和進程同步的結論
結論:
互斥------------因爲緩衝區是臨界資源,各種進程必須互斥的訪問(即不能同時訪問)。
同步1-----------只有緩衝區不空時,消費者纔可以從緩衝區中取產品,即 “ 先生產後消費 ”。
同步2-----------只有緩衝區不滿時,生產者纔可以往緩衝區中放產品,即 “ 先消費後生產”。
具體解法:
semaphore mutex=1;//互斥信號量 ,實現對緩衝區的互斥訪問 semaphore full =0;//同步1信號量,表示產品的數量 semaphore empty=n;//同步2信號量,表示空閒區的數量 producer() { while(1) { 生產一個產品; P(empty); P(mutex); 將產品放入緩衝區; V(mutex); V(full); } } consumer() { while(1) { P(full); P(mutex); 從緩衝區取出一個產品; V(mutex); V(empty); 使用一個產品; } }
討論:
1.生產者和消費者進程都有兩個P操作在一塊,可以把生產者的兩個P操作或者消費者的兩個P操作調換順序嗎?
答案:無論是生產的的兩個P操作,還是消費者的兩個P操作都不可以調換順序。假如生產的的兩個P操作調換了順序(包含了消費者換或者不換兩種情況),現在有一種情況是empy=0,full=n,在這種情況下,假設消費者進程先執行,
生產一個產品------>P(mutex)佔用緩衝區,這時候除非等消費者釋放緩衝區,不然誰也無法使用緩衝區了
-------->P(empty)因爲empty=0,所以執行block原語,將生產的進程從運行態轉到阻塞態,經過這一步之後消費者進程阻塞,只能等切換進程,假如切換到消費者進程,無論P(mutex)在P(full)前還是在P(full)後,總歸要執行P(mutex),但是生產者正在佔用緩衝區,因此就產生了死鎖。
調換消費的的兩個P操作順序也是類似,在empty=n,full=0的情況下也不滿足,如果不懂得話,自己可以按照上面的進行推導。
2.生產者和消費者進程都有兩個V操作在一塊,可以把生產者的兩個V操作或者消費者的兩個V操作調換順序嗎?
答案:可以
注意:如果看完分析還是不懂,再去把進程的互斥和進程的同步看一遍,一點要把這兩個弄清楚。