PV操作和讀者寫者問題是進程間相互作用的經典問題,今天我就用幼兒園都能看懂的大白話來把這個問題講清楚。
我們都知道,現代操作系統中能同時運行多個程序,而每一個運行中的程序,就叫一個進程。這些進程有些是互不相干,各跑各的;而有些進程,它們可能會共享某些數據,需要相互協作才能正確運行,我們管這樣的進程叫:相關進程。
舉個簡單的例子:流水線上的操作工A和B需要按順序生產產品,A和B之間有一個加工容器,A負責將產品放進容器,然後B負責從容器取走產品,而這個容器一次只能容納一個產品,如果A放的太快,就會放不下;如果B拿的太快,就會拿空。
車間主管一來,想了個辦法,
對A說:A你每次放之前,就先問一聲:“空了嗎?”,要是空的呢,你就放,放好你就再喊一聲:“滿了!”;要是不空呢,你就先等着,等B拿走了,他會叫你的!
又對B說:B你每次拿之前,也問一聲:“滿了嗎?”,要是滿的呢,你就拿,拿走你也喊一聲:“空了!”;要是不滿呢,你就先等着,等A放好了,他會叫你的!
於是A和B便按主管說的,一起愉快的幹了下去。
在這個問題中,爲了確保正確的工作,A和B其實只關心各自的1個問題。A關心的是容器空了沒有,空了我就放;而B關心的則是容器滿了沒有,滿了我就拿。所以我們可以把A和B看做兩個相關進程P1和P2,而他們各自關心的問題 "空了嗎" 和 "滿了嗎" 分別用兩個信號量empty和full來表示,讓empty=1,讓full=0,至於爲什麼一個是1一個是0我們後面再講,先記着就好了。
先來看進程P1也就是放產品的進程,它的工作流是這樣的:
- 問一聲:"空了嗎?"
- 如果是滿的,就等着
- 如果是空的,就放產品
- 喊一聲:"滿了!"
寫成僞代碼就是:
while(true){
while( "空了嗎?" 爲 false){
//等着
}
放產品;
喊一聲:"滿了!";
}
我們可以看到,等待的部分,我們是用while來實現的。事實上,P操作就是用來幫我們幹這個的。
用P操作修改之後的代碼如下:
empty = 1;
while(true){
P(empty); //問一聲:"空了嗎?";如果不空,就會在這等着
放產品;
喊一聲:"滿了!";
}
----------------------------------- 馬上要考試了,先去看書了,下次再更,srysry 。2019/10/11 -----------------------------------