操作系统pv操作学习总结
生活随笔
收集整理的這篇文章主要介紹了
操作系统pv操作学习总结
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
PV操作
PV操作與信號量的處理相關,P表示通過的意思,V表示釋放的意思。目錄
1 簡介
2 詳細資料
3 解釋
? 信號量的概念
? 典型理解偏差
簡介
1962年,狄克斯特拉離開數學中心進入位于荷蘭南部的艾恩德霍芬技術大學(Eindhoven Technical University)任數學教授。在這里,他參加了X86計算機的開發,設計與實現了具有多道程序運行能力的操作系統——THE Multiprogramming System。
詳細資料
THE 是艾恩德霍芬技術大學的荷蘭文Tchnische Hoogeschool Eindhov –en的詞 頭縮寫。狄克斯特拉在THE這個系統中所提 出的一系統方法和技術奠定了計算機現代操作系統的基礎,尤其是關于多層體系結構,順序進程之間的同步和互斥機制這樣一些重要的思想和概念都是狄克斯特拉在THE中首先提出并為以后的操作系統如UNⅨ等所采用的。
為了在單處理機的情況下確定進程(process)能否占有處理機,狄克斯特拉將每個進程分為“就緒”(ready)、“運行”(running)和“阻塞”(blocking)三個工作 狀態。由于在任一時刻最多只有一個進程可以使用處理機,正占用著處理機的進程稱為“運行”進程。當某進程已具備了使用處理機的條 件,而當前又沒有處理機供其使用,則使該進程處于“就緒”狀態。當運行進程由于某種原因無法繼續運行下去時,就停止其占用處理機,使之進入“阻塞”狀態,待造成其退出運行的條件解除,再進入“就緒”狀態。而對系統中所有同時運行的進程之間所存在的相互制約的同步(synchronization,指為了避免錯誤,在一個進程訪問共享數據時,另一個進程不訪問該數據)和互斥(mutually-exclusive,指兩個進程不能同時在一個臨界區中使用同一個可重復使用的資源,諸如讀寫緩沖區)兩個關系,狄克斯特拉巧妙地利用火車運行控制系統中的“信號燈”(semaphore,或叫“信號量”)概念加以解決。
所謂信號燈,實際上就是用來控制進程狀態的一個代表某一資源的存儲單元。例如,P1和P2是分別將數據送入緩沖B和從緩沖B讀出數據的兩個進程,為了防止這兩個進程并發時產生錯誤,狄克斯特拉設計了一種同步機制叫“PV操作”,P操作和V操作是執行時不被打斷的兩個操作系統原語。執行P操作P(S)時信號量S的值減1,若結果不為負則P(S)執行完畢,否則執行P操作的進程暫停以等待釋 放。執行V操作V(S)時,S的值加1,若結果不大于0則釋放一個因執行P(S)而等待的進程。對P1和P2可定義兩 個信號量S1和S2,初 值分別為1和0。進程P1在向緩沖B送入數據前執行P操 作P(S1),在送入數據后執行V操 作V(S2)。進程P2在從緩沖B讀取數 據前先執行P操作P(S2),在讀出數據 后執行V操作V(S1)。當P 1往緩沖B送入一數據后信號量S1之值變為0,在該數據讀出后S1之值才又變為1,因此在前一數未讀出前 后一數不會送入,從而保 證了P1和P2之間的同步。
中國讀者常常不明白這一同步機制為什么叫PV操作,原 來這是狄克斯特拉用荷蘭文定義的,因為在荷 蘭文中,通過叫passeren,釋放叫vrijgeven,PV操 作因此得名。這是在計算機術語中不是用英 語表達的極少數的例子之一。
解釋
1962年,狄克斯特拉離開數學中心進入位于荷蘭南部的艾恩德霍芬技術大學(EindhovenTechnical University)任數學教授。在這里,他參加了X8計算機的開發,設計與實現了具有多道程序運行能力的操作系統——THE Multiprogramming System。THE是艾恩德霍芬技術大學的荷蘭文Tchnische Hoogeschool Eindhov –en的詞頭縮寫。狄克斯特拉在THE這個系統中所提出的一系統方法和技術奠定了計算機現代操作系統的基礎,尤其是關于多層體系結構,順序進程之間的同步和互斥機制這樣一些重要的思想和概念都是狄克斯特拉在THE中首先提出并為以后的操作系統如UNⅨ等所采用的。為了在單處理機的情況下確定進程(process)能否占有處理機,狄克斯特拉將每個進程分為“就緒”(ready)、“運行”(running)和“阻塞”(blocking)三個工作狀態。由于在任一時刻最多只有一個進程可以使用處理機,正占用著處理機的進程稱為“運行”進程。當某進程已具備了使用處理機的條件,而當前又沒有處理機供其使用,則使該進程處于“就緒”狀態。當運行進程由于某種原因無法繼續運行下去時,就停止其占用處理機,使之進入“阻塞”狀態,待造成其退出運行的條件解除,再進入“就緒”狀態。而對系統中所有同時運行的進程之間所存在的相互制約的同步(synchronization,指為了避免錯誤,在一個進程訪問共享數據時,另一個進程不訪問該數據)和互斥(mutually-exclusive,指兩個進程不能同時在一個臨界區中使用同一個可重復使用的資源,諸如讀寫緩沖區)兩個關系,狄克斯特拉巧妙地利用火車運行控制系統中的“信號燈”(semaphore,或叫“信號量”)概念加以解決。所謂信號燈,實際上就是用來控制進程狀態的一個代表某一資源的存儲單元。例如,P1和P2是分別將數據送入緩沖B和從緩沖B讀出數據的兩個進程,為了防止這兩個進程并發時產生錯誤,狄克斯特拉設計了一種同步機制叫“PV操作”,P操作和V操作是執行時不被打斷的兩個操作系統原語。執行P操作P(S)時信號量S的值減1,若結果大于等于0,則P(S)執行完畢,否則執行P操作的進程暫停以等待釋放。執行V操作V(S)時,S的值加1,若結果大于0,則釋放一個因執行P(S)而等待的進程。對P1和P2可定義兩個信號量S1和S2,初值分別為1和0。進程P1在向緩沖B送入數據前執行P操作P(S1),在送入數據后執行V操作V(S2)。進程P2在從緩沖B讀取數據前先執行P操作P(S2),在讀出數據后執行V操作V(S1)。當P1往緩沖B送入一數據后信號量S1之值變為0,在該數據讀出后S1之值才又變為1,因此在前一數未讀出前后一數不會送入,從而保證了P1和P2之間的同步。
信號量是最早出現的用來解決進程同步與互斥問題的機制,
包括一個稱為信號量的變量及對它進行的兩個原語操作。
信號量的概念
1.信號量的類型定義
信號量(semaphore)的數據結構為一個值和一個指針,指針指向等待該信號量的下一個進程。信號量的值與相應資源的使用情況有關。當它的值大于0時,表示當前可用資源的數量;當它的值小于0時,其絕對值表示等待使用該資源的進程個數。注意,信號量的值僅能由PV操作來改變。
一般來說,信號量S>=0時,S表示可用資源的數量。執行一次P操作意味著請求分配一個單位資源,因此S的值減1;當S<0時,表示已經沒有可用資源,請求者必須等待別的進程釋放該類資源,它才能運行下去。而執行一個V操作意味著釋放一個單位資源,因此S的值加1;若S<0,表示有某些進程正在等待該資源,因此要喚醒一個等待狀態的進程,使之運行下去。
2.PV原語
PV操作是典型的同步機制之一。用一個信號量與一個消息聯系起來,當信號量的值為0時,表示期望的消息尚未產生;當信號量的值非0時,表示期望的消息已經存在。用P V操作實現進程同步時,調用P操作測試消息是否到達,調用V操作發送消息。
對一個信號量變量可以進行兩種原語操作:p操作和v操作,定義如下:procedure p(var s:semaphore);
{
s.value=s.value-1;
if (s.value<0) asleep(s.queue);
}
procedure v(var s:samephore);
{
s.value=s.value+1;
if (s.value<=0) wakeup(s.queue);
}
其中用到兩個標準過程:
asleep(s.queue);執行此操作的進程的PCB進入s.queue尾部,進程變成等待狀態
wakeup(s.queue);將s.queue頭進程喚醒插入就緒隊列
s.value初值為1時,可以用來實現進程的互斥。
p操作和v操作是不可中斷的程序段,稱為原語。如果將信號量看作共享變量,則pv操作為其臨界區,多個進程不能同時執行,一般用硬件方法保證。一個信號量只能置一次初值,以后只能對之進行p操作或v操作。
由此也可以看到,信號量機制必須有公共內存,不能用于分布式操作系統,這是它最大的弱點。
V原語的主要操作是:
⑴sem加1;
⑵若相加結果大于零,則進程繼續執行;
⑶若相加結果小于或等于零,則喚醒一阻塞在該信號量上的進程,然后再返回原進程繼續執行或轉進程調度。
利用信號量和PV操作實現進程互斥的一般模型是:
進程P1 進程P2 …… 進程Pn
…… …… ……
P(S); P(S); P(S);
臨界區; 臨界區; 臨界區;
V(S); V(S); V(S);
…… …… …… ……
其中信號量S用于互斥,初值為1。
使用PV操作實現進程互斥時應該注意的是:
⑴每個程序中用戶實現互斥的P、V操作必須成對出現,先做P操作,進臨界區,后做V操作,出臨界區。若有多個分支,要認真檢查其成對性。
⑵P、V操作應分別緊靠臨界區的頭尾部,臨界區的代碼應盡可能短,不能有死循環。
⑶互斥信號量的初值一般為1。
利用信號量和PV操作實現進程同步:
PV操作是典型的同步機制之一。用一個信號量與一個消息聯系起來,當信號量的值為0時,表示期望的消息尚未產生;當信號量的值非0時,表示期望的消息已經存在。用PV操作實現進程同步時,調用P操作測試消息是否到達,調用V操作發送消息。
使用PV操作實現進程同步時應該注意的是:
⑴分析進程間的制約關系,確定信號量種類。在保持進程間有正確的同步關系情況下,哪個進程先執行,哪些進程后執行,彼此間通過什么資源(信號量)進行協調,從而明確要設置哪些信號量。
⑵信號量的初值與相應資源的數量有關,也與P、V操作在程序代碼中出現的位置有關。
⑶同一信號量的P、V操作要成對出現,但它們分別在不同的進程代碼中。
典型理解偏差
三個問題:
一,以V原語的1、2步來做,Sem不就永遠大于0,那進程不就一直循環執行成為死循環了?
二,Sem大于0那就表示有臨界資源可供使用,為什么不喚醒進程?
三,Sem小于0應該是說沒有臨界資源可供使用,為什么還要喚醒進程?
析疑:
一,P操作對sem減1的。P、V原語必須成對使用!從而不會造成死循環。
二,Sem大于0的確表示有臨界資源可供使用,而且這個時候沒有進程被阻塞在這個資源上,也就是說沒有進程因為得不到這類資源而阻塞,所以沒有被阻塞的進程,自然不需要喚醒。
三,V原語操作的本質在于:一個進程使用完臨界資源后,釋放臨界資源,使Sem加1,以通知其它的進程,這個時候如果Sem<0,表明有進程阻塞在該類資源上,因此要從阻塞隊列里喚醒一個進程來“轉手”該類資源。比如,有兩個某類資源,四個進程A、B、C、D要用該類資源,最開始Sem=2,當A進入,Sem=1,當B進入Sem=0,表明該類資源剛好用完, 當C進入時Sem=-1,表明有一個進程被阻塞了,D進入,Sem=-2。當A用完該類資源時,進行V操作,Sem=-1,釋放該類資源,而這時Sem<0,表明有進程阻塞在該類資源上,于是喚醒一個。
為了進一步加深理解,再引入二個問題:
四,如果是互斥信號量的話,應該設置信號量Sem=1,但是當有5個進程都訪問的話,最后在該信號量的鏈表里會有4個在等待,也是說S=-4,那么第一個進程執行了V操作使S加1,釋放了資源,下一個應該能夠執行,但喚醒的這個進程在執行P操作時因S〈0,也還是執行不了,這是怎么回事呢?
五,Sem的絕對值表示等待的進程數,同時又表示臨界資源,這到底是怎么回事?
析疑:
四,當一個進程阻塞了的時候,它已經執行過了P操作,并卡在臨界區那個地方。當喚醒它時就立即進入它自己的臨界區,并不需要執行P操作了,當執行完了臨界區的程序后,就執行V操作。
五,當信號量Sem小于0時,其絕對值表示系統中因請求該類資源而被阻塞的進程數目.S大于0時表示可用的臨界資源數。注意在不同情況下所表達的含義不一樣。當等于0時,表示剛好用完。
========
操作系統之PV操作實例分析
http://blog.csdn.net/wulingmin21/article/details/7492737 ?? ? 剛開始學習操作系統的時候,就聽說PV操作,簡單說說PV操作。
● ?P(S): S=S-1?
? ? ? ? ? ? 如果S≥0,則該進程繼續執行;
? ? ? ? ? ? ? S<0,進程暫停執行,放入信號量的等待隊列
?
● ?V(S): S=S+1
? ? ? ? ? ? 如果S>0,則該進程繼續執行;
? ? ? ? ? ? ? ? S≤0, 喚醒等待隊列中的一個進程
? ? 到底怎么分析,下面看看一個具體的問題:
? ??
首先設信號量S1,S2,其中
S1,表示是否允許司機啟動汽車,其初值為0,
S2,表示是否允許售票員開車門,初值為O;
? ? ??
● 分析:
? ? 司機進程:
? ? ? ? ? ? P:S1=S1-1 得:S1=0-1=-1<0 司機進程暫停執行,放入信號量的等待隊列(售票員進程)
?
? ? 售票員進程:
? ? ? ? ? ?關車門;
? ? ? ? ? ?V:S1=S1+1得:S1=-1+1=0≤ 0 ?喚醒等待隊列中的一個進程
? ? (解釋:喚醒司機進程,使司機進程成為就緒狀態,司機可以啟動車輛,正常行駛,……,直到到V(S2), ?S2=S2+1 得:S2=0+1=1>0 ,司機進程在此時往下就沒有操作了;
在喚醒司機進程的同時,售票員可以售票,執行售票進程,到P(S2)。
如果之前司機進程到V(S2),這里P(S2):S2=S2-1得:S2=1-1=0 ≥ 0,接著往下執行,到最后上下客;
如果之前司機進程未到V(S2),售票員的進程到P(S2),則如下進行)
? ? ? ? ? ?售票;(同時司機可能,啟動車輛;正常行駛;……)
? ? ? ? ? ?P:S2=S2-1得:S2=0-1=-1< 0 售票員進程暫停執行,放入信號量的等待隊列(運行司機進程)
?
? ? 司機進程: ??
? ? ? ? ?(接著上面未完成的繼續往下執行)
? ? ? ? ? 啟動車輛;
? ? ? ? ? 正常行駛;
? ? ? ? ? 到站停車;
? ? ? ? ? ?S2=S2+1 得:S2=-1+1=0≤ 0 喚醒等待隊列中的一個進程(運行售票員進程)
?
? ? 售票員進程:
? ? ? ? 開車門;
? ? ? ? 上下客;
? ? 以上過程(可以是如下):
? ? ? ? ??
? ? ?在售票員進程進程到V(S1),往下售票的同時司機可以啟動車輛、……
● 使用PV操作實現進程同步時應該注意的是:
? ? (1)分析進程間的制約關系,確定信號量種類。在保持進程間有正確的同步關系情況下,哪個進程先執行,哪些進程后執行,彼此間通過什么資源(信號量)進行協調,從而明確要設置哪些信號量。
? ? (2)信號量的初值與相應資源的數量有關,也與P、V操作在程序代碼中出現的位置有關。
? ? (3)同一信號量的P、V操作要成對出現,但它們分別在不同的進程代碼中。
========
操作系統—PV操作
http://blog.csdn.net/wzh402/article/details/44889671? ? ? ?大家都說操作系統中的PV操作部分看不懂,確實我在專業課中學習這門課時,PV操作被列為書中的重點和難點,就是因為它不好理解。當時自己聽完課也是一頭霧水,到期末考試結束,也沒弄明白這是怎么一回事,更沒有意識到PV操作的重要性。米老師的一堂課,讓我開始對它產生興趣,于是才有了這篇博客。首先就來說說什么是PV操作吧!
? ? ? ?什么是PV操作?
? ? ? ?在說什么是PV操作前,首先講講它的歷史(咱也像寫書的人一樣,上來先介紹它的歷史和發展)
? ? ? ?PV操作是有名的計算機科學家狄克斯特拉為了解決一類問題而創造的,例如:假如P1和P2是分別將數據送入緩沖B和從緩沖B讀出數據的兩個進程,為了防止這兩個進程并發時產生錯誤,狄克斯特拉設計了一種同步機制叫“PV操作”。我相信,很多人都很納悶為什么他會取名叫“PV”操作呢?其實這是狄克斯特拉用荷蘭文定義的,因為在荷蘭文中,“通過”叫passeren,“釋放”叫vrijgeven,PV操作因此得名。這也是在計算機術語中不是用英語表達的極少數的例子之一。
? ? ? ?說了那么多,那到底什么叫PV操作呢?PV操作有P操作和V操作組成,它們是兩個不可中斷的過程,也叫做原語。它是為了能夠實現對于并發進程中臨界區的管理要求。
? ? ? ?為什么要有PV操作?
? ? ? ?其實這個問題上面也說到了,是為了防止兩個進程并發時產生錯誤。這里不得不說的就是,并發進程之間分為兩種,一種就是有交互的,一種是無任何關聯的。
? ? ? ?很簡單,沒有關聯的并發進程是相互獨立的,誰也不影響誰。但是交互的并發進程可就不一樣了,因為他們是共享資源的,一個進程運行時,經常會由于自身或外界的原因而被中端,且斷點是不固定的。也就是說進程執行的相對速度不能由進程自己來控制,于是就會導致并發進程在共享資源的時出現與時間有關的錯誤。
? ? ? ?PV操作的使用
? ? ? ?名詞解釋
? ? ? ?臨界區:我們把并發進程中與共享變量有關的程序段稱為臨界區。
? ? ? ?信號量S:信號量的值與相應資源的使用情況有關。當它的值大于0時,表示當前可用資源的數量;當它的值小于0時,其絕對值表示等待使用該資源的進程個數。
? ? ? ?P操作和V操作
? ? ? ?P操作P(S):將信號量S減去1,若結果小于0,則把調用P(S)的進程置成等待信號量S的狀態。即為請求資源。
? ? ? ?V操作V(S):將信號量S加上1,若結果不大于0,則釋放一個等待信號量S的進程。即為釋放資源。
? ? ? ?表示過程如下:
? ? ? ?Procedure P (Var S:Semaphore)
? ? ? ?begin
? ? ? ? ? ?S:=S - 1;
? ? ? ? ? ?if S<0 then W(S)?
? ? ? ?end; { P }
? ? ? ?
? ? ? ?Procedure V (Var S:Semaphore)
? ? ? ?begin
? ? ? ? ? ?S:=S + 1;
? ? ? ? ? ?if S< = 0 then R(S)?
? ? ? ?end; { V }
? ? ? ?注解:
? ? ? ?W(S):表示把調用P(S)的進程置成等待信號量S的狀態。
? ? ? ?R(S):表示釋放一個等待信號量S的進程。
? ? ? ?正如老師上課時所舉的父親給孩子吃蘋果的例子一樣,假如一個盤子只能放一個蘋果,父親往盤子里放了一個蘋果。如果兒子吃了(V操作),父親才可以接著放(P操作);如果兒子不吃,那父親就不能放蘋果,只能等著。
? ? ? ?進程互斥和進程同步
? ? ? ?進程互斥
? ? ? ?進程的互斥是指當有若干個進程都要使用某一共享資源時,任何時刻最多只允許一個進程去使用該資源,其他要使用它的進程必須等待,直到該資源的占用著釋放了該資源。
? ? ? ?例如:兩個并發進程都要使用共享的計數器Count。
? ? ? ?
[csharp] view plain copy print?
begin ?
? ? ? count:integer; ?
? ? ? S:semaphore; ?
? ? ? count:= 0 //計數器count初始值為0 ?
? ? ? S:= 1 //信號量初始值為1 ?
? ?cobegin ?
? ? ? ?//進程PIN ?
? ? ? ?process PIN ?
? ? ? ?R1:integer; ?
? ? ? ?begin ?
? ? ? ? ? ? P(S); ?//執行P操作 ?
? ? ? ? ? ? R1:= count; ?
? ? ? ? ? ? R1:= R1 + 1; ?
? ? ? ? ? ? count:= R1; ?
? ? ? ? ? ? V(S) ?//執行V操作 ?
? ? ? ? end; ?
? ? ? ?//進程POUT ?
? ? ? ?process POUT ?
? ? ? ?R2:integer; ?
? ? ? ?begin ?
? ? ? ? ? ? P(S); ?//執行P操作 ?
? ? ? ? ? ? R2:= count; ?
? ? ? ? ? ? R2:= R2 + 1; ?
? ? ? ? ? ? count:= R2; ?
? ? ? ? ? ? V(S) ?//執行V操作 ?
? ? ? ? end; ?
? ?coend ?
end; ?
? ? ? ?進程同步
? ? ? ?進程的同步是指在并發進程之間存在這一種制約關系,一個進程依賴另一個進程的消息,當一個進程沒有得到另一個進程的消息時應等待,直到消息到達才被喚醒。
? ? ? ?例如:一個司機與售票員的例子,在公共汽車上,為保證乘客的安全,司機和售票員應協調工作:停車后才能開門,關車門后才能行車。用PV操作來實現他們之間的協調。
? ? ? ?S1:是否允許司機啟動汽車的變量
? ? ? ?S2:是否允許售票員開門的變量
[csharp] view plain copy print?
driver()//司機進程 ?
{ ?
? while (1)//不停地循環 ?
? { ??
? ?P(S1);//請求啟動汽車 ?
? ?啟動汽車; ?
? ?正常行車; ?
? ?到站停車; ?
? ?V(S2); //釋放開門變量,相當于通知售票員可以開門 ?
? } ?
} ?
[csharp] view plain copy print?
busman()//售票員進程 ?
{ ?
? ?while(1) ?
? ?{ ?
? ? 關車門; ?
? ? V(S1);//釋放開車變量,相當于通知司機可以開車 ?
? ? 售票 ?
? ? P(S2);//請求開門 ?
? ? 開車門; ?
? ? 上下乘客; ?
? ?} ?
} ?
? ? ? ?總結:
? ? ? ?PV操作是操作系統中的重點和難點,不過如果細細分析,知道為什么要使用它以后。其實發現,PV操作也不過如此。并發進程間可以通過PV操作交換信息實現進程的互斥和同步,因此PV操作可以看做是進程間的一種低級的通信方式,只交換了少量的信息。但它解決了進程間對于資源共享而產生的與時間有關的錯誤。
========
信號量與PV操作
http://blog.chinaunix.net/uid-15014334-id-2853109.html在計算機操作系統中,PV操作是進程管理中的難點。
首先應弄清PV操作的含義:PV操作由P操作原語和V操作原語組成(原語是不可中斷的過程),對信號量進行操作,具體定義如下:
? ? P(S):①將信號量S的值減1,即S=S-1;
? ? ? ? ? ?②如果S30,則該進程繼續執行;否則該進程置為等待狀態,排入等待隊列。
? ? V(S):①將信號量S的值加1,即S=S+1;
? ? ? ? ? ?②如果S>0,則該進程繼續執行;否則釋放隊列中第一個等待信號量的進程。
PV操作的意義:我們用信號量及PV操作來實現進程的同步和互斥。PV操作屬于進程的低級通信。
什么是信號量?信號量(semaphore)的數據結構為一個值和一個指針,指針指向等待該信號量的下一個進程。信號量的值與相應資源的使用情況有關。當它的值大于0時,表示當前可用資源的數量;當它的值小于0時,其絕對值表示等待使用該資源的進程個數。注意,信號量的值僅能由PV操作來改變。
? ? ?一般來說,信號量S30時,S表示可用資源的數量。執行一次P操作意味著請求分配一個單位資源,因此S的值減1;當S<0時,表示已經沒有可用資源,請求者必須等待別的進程釋放該類資源,它才能運行下去。而執行一個V操作意味著釋放一個單位資源,因此S的值加1;若S£0,表示有某些進程正在等待該資源,因此要喚醒一個等待狀態的進程,使之運行下去。
? ? 利用信號量和PV操作實現進程互斥的一般模型是:
進程P1 ? ? ? ? ? ? ?進程P2 ? ? ? ? ? …… ? ? ? ? ?進程Pn
…… ? ? ? ? ? ? ? ? ?…… ? ? ? ? ? ? ? ? ? ? ? ? ? ……
P(S); ? ? ? ? ? ? ?P(S); ? ? ? ? ? ? ? ? ? ? ? ? P(S);
臨界區; ? ? ? ? ? ? 臨界區; ? ? ? ? ? ? ? ? ? ? ? ?臨界區;
V(S); ? ? ? ? ? ? ?V(S); ? ? ? ? ? ? ? ? ? ? ? ?V(S);
…… ? ? ? ? ? ? ? ? ?…… ? ? ? ? ? ?…… ? ? ? ? ? ……
? ? 其中信號量S用于互斥,初值為1。
? ? 使用PV操作實現進程互斥時應該注意的是:
? ? (1)每個程序中用戶實現互斥的P、V操作必須成對出現,先做P操作,進臨界區,后做V操作,出臨界區。若有多個分支,要認真檢查其成對性。
? ? (2)P、V操作應分別緊靠臨界區的頭尾部,臨界區的代碼應盡可能短,不能有死循環。
? ?(3)互斥信號量的初值一般為1。
? ? 利用信號量和PV操作實現進程同步
PV操作是典型的同步機制之一。用一個信號量與一個消息聯系起來,當信號量的值為0時,表示期望的消息尚未產生;當信號量的值非0時,表示期望的消息已經存在。用PV操作實現進程同步時,調用P操作測試消息是否到達,調用V操作發送消息。
? ? 使用PV操作實現進程同步時應該注意的是:
? ? (1)分析進程間的制約關系,確定信號量種類。在保持進程間有正確的同步關系情況下,哪個進程先執行,哪些進程后執行,彼此間通過什么資源(信號量)進行協調,從而明確要設置哪些信號量。
? ? (2)信號量的初值與相應資源的數量有關,也與P、V操作在程序代碼中出現的位置有關。
? ? (3)同一信號量的P、V操作要成對出現,但它們分別在不同的進程代碼中。
【例1】生產者-消費者問題
在多道程序環境下,進程同步是一個十分重要又令人感興趣的問題,而生產者-消費者問題是其中一個有代表性的進程同步問題。下面我們給出了各種情況下的生產者-消費者問題,深入地分析和透徹地理解這個例子,對于全面解決操作系統內的同步、互斥問題將有很大幫助。
(1)一個生產者,一個消費者,公用一個緩沖區。
定義兩個同步信號量:
empty——表示緩沖區是否為空,初值為1。
? ?full——表示緩沖區中是否為滿,初值為0。
生產者進程
while(TRUE){
生產一個產品;
? ? ?P(empty);
? ? ?產品送往Buffer;
? ? ?V(full);
}
消費者進程
while(True){
P(full);
? ?從Buffer取出一個產品;
? ?V(empty);
? ?消費該產品;
? ?}
(2)一個生產者,一個消費者,公用n個環形緩沖區。
定義兩個同步信號量:
empty——表示緩沖區是否為空,初值為n。
full——表示緩沖區中是否為滿,初值為0。
? ? 設緩沖區的編號為1~n-1,定義兩個指針in和out,分別是生產者進程和消費者進程使用的指
,指向下一個可用的緩沖區。
生產者進程
while(TRUE){
? ? ?生產一個產品;
? ? ?P(empty);
? ? ?產品送往buffer(in);
? ? ?in=(in+1)mod n;
? ? ?V(full);
}
消費者進程
while(TRUE){
?P(full);
? ?從buffer(out)中取出產品;
? ?out=(out+1)mod n;
? ?V(empty);
? ?消費該產品;
? ?}
(3)一組生產者,一組消費者,公用n個環形緩沖區
? ? 在這個問題中,不僅生產者與消費者之間要同步,而且各個生產者之間、各個消費者之間還必須互斥地訪問緩沖區。
定義四個信號量:
empty——表示緩沖區是否為空,初值為n。
full——表示緩沖區中是否為滿,初值為0。
mutex1——生產者之間的互斥信號量,初值為1。
mutex2——消費者之間的互斥信號量,初值為1。
? ? 設緩沖區的編號為1~n-1,定義兩個指針in和out,分別是生產者進程和消費者進程使用的指針,指向下一個可用的緩沖區。
生產者進程
while(TRUE){
? ? ?生產一個產品;
? ? ?P(empty);
? ? ?P(mutex1);
? ? ?產品送往buffer(in);
? ? ?in=(in+1)mod n;
? ? ?V(mutex1);
? ? ?V(full);
}
消費者進程
while(TRUE){
?P(full)
? ?P(mutex2);
? ?從buffer(out)中取出產品;
? ?out=(out+1)mod n;
? ?V(mutex2);
? ?V(empty);
? ?消費該產品;
? ?}
? 需要注意的是無論在生產者進程中還是在消費者進程中,兩個P操作的次序不能顛倒。應先執行同步信號量的P操作,然后再執行互斥信號量的P操作,否則可能造成進程死鎖。
【例2】桌上有一空盤,允許存放一只水果。爸爸可向盤中放蘋果,也可向盤中放桔子,兒子專等吃盤中的桔子,女兒專等吃盤中的蘋果。規定當盤空時一次只能放一只水果供吃者取用,請用P、V原語實現爸爸、兒子、女兒三個并發進程的同步。
分析 在本題中,爸爸、兒子、女兒共用一個盤子,盤中一次只能放一個水果。當盤子為空時,爸爸可將一個水果放入果盤中。若放入果盤中的是桔子,則允許兒子吃,女兒必須等待;若放入果盤中的是蘋果,則允許女兒吃,兒子必須等待。本題實際上是生產者-消費者問題的一種變形。這里,生產者放入緩沖區的產品有兩類,消費者也有兩類,每類消費者只消費其中固定的一類產品。
? ? 解:在本題中,應設置三個信號量S、So、Sa,信號量S表示盤子是否為空,其初值為l;信號量So表示盤中是否有桔子,其初值為0;信號量Sa表示盤中是否有蘋果,其初值為0。同步描述如下:
int S=1;
int Sa=0;
int So=0;
? ? ? main()
? ? ? {
? ? ? ? cobegin
? ? ? ? ? ? father(); ? ? ?/*父親進程*/
? ? ? ? ? ? son(); ? ? ? ?/*兒子進程*/
? ? ? ? ? ? daughter(); ? ?/*女兒進程*/
? ? ? ? coend
? ? }
? ? father()
? ? {
? ? ? ? while(1)
? ? ? ? ? {
? ? ? ? ? ? P(S);
? ? ? ? ? ? 將水果放入盤中;
? ? ? ? ? ? if(放入的是桔子)V(So);
? ? ? ? ? ? else ?V(Sa);
? ? ? ? ? ?}
? ? ?}
? ? son()
? ? {
? ? ? ? while(1)
? ? ? ? ? {
? ? ? ? ? ? ?P(So);
? ? ? ? ? ? ?從盤中取出桔子;
? ? ? ? ? ? ?V(S);
? ? ? ? ? ? ?吃桔子;
? ? ? ? ? ? }
? ? }
? ? daughter()
? ? {
? ? ? ? ?while(1)
? ? ? ? ? ? {
? ? ? ? ? ? ? P(Sa);
? ? ? ? ? ? ? 從盤中取出蘋果;
? ? ? ? ? ? ? V(S);
? ? ? ? ? ? ? 吃蘋果;
? ? ? ? ? ? }
}
?
思考題:
四個進程A、B、C、D都要讀一個共享文件F,系統允許多個進程同時讀文件F。但限制是進程A和進程C不能同時讀文件F,進程B和進程D也不能同時讀文件F。為了使這四個進程并發執行時能按系統要求使用文件,現用PV操作進行管理,請回答下面的問題:
? ? (1)應定義的信號量及初值: ? ? ? ? ? ? ? ? ? ?。
? ? (2)在下列的程序中填上適當的P、V操作,以保證它們能正確并發工作:
? ? ?A() ? ? ? ? ? ? ? ?B() ? ? ? ? ? ? ? ? ?C() ? ? ? ? ? ? ? ? D()
? ? ? { ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ?{ ? ? ? ? ? ? ? ? ?{
? ? ? [1]; ? ? ? ? ? ? ? ?[3]; ? ? ? ? ? ? ? ? ?[5]; ? ? ? ? ? ? ? ? [7];
? ? ? read F; ? ? ? ? ? ? read F; ? ? ? ? ? ? ? ?read F; ? ? ? ? ? ? ?read F;
? ? ?[2]; ? ? ? ? ? ? ? ?[4]; ? ? ? ? ? ? ? ? ?[6]; ? ? ? ? ? ? ? ? [8];
? ? ? } ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ? ?}?
? ? 思考題解答:
(1)定義二個信號量S1、S2,初值均為1,即:S1=1,S2=1。其中進程A和C使用信號量S1,進程B和D使用信號量S2。
(2)從[1]到[8]分別為:P(S1) V(S1) P(S2) V(S2) P(S1) V(S1) P(S2) V(S2)
?
具體PV原語對信號量的操作可以分為三種情況:
1) ? ? ? ? ? ? ?把信號量視為一個加鎖標志位,實現對一個共享變量的互斥訪問。
實現過程:
P(mutex); ? ? ? ? ? // mutex的初始值為1
訪問該共享數據;
V(mutex);
非臨界區
2) ? ? ? ? ? ? ?把信號量視為是某種類型的共享資源的剩余個數,實現對一類共享資源的訪問。
實現過程:
P(resource); ? ? ? ? ?// resource的初始值為該資源的個數N
使用該資源;
V(resource);
非臨界區
3) ? ? ? ? ? ? ?把信號量作為進程間的同步工具
實現過程:
臨界區C1; ? ?P(S);
V(S); ? ? ? ? ? 臨界區C2;
?
下面用幾個例子來具體說明:
例1:某超市門口為顧客準備了100輛手推車,每位顧客在進去買東西時取一輛推車,在買完東西結完帳以后再把推車還回去。試用P、V操作正確實現顧客進程的同步互斥關系。
分析:把手推車視為某種資源,每個顧客為一個要互斥訪問該資源的進程。因此這個例子為PV原語的第二種應用類型。
解:semaphore ?S_CartNum; ? // 空閑的手推車數量, 初值為100
void ?consumer(void) ? ? ? ? ? // 顧客進程
{
? ? ? ? P(S_CartNum);
? ? ? ? 買東西;
? ? ? ? 結帳;
? ? ? ? V(S_CartNum);?
}
例2:桌子上有一個水果盤,每一次可以往里面放入一個水果。爸爸專向盤子中放蘋果,兒子專等吃盤子中的蘋果。把爸爸、兒子看作二個進程,試用P、V操作使這四個進程能正確地并發執行。
分析:爸爸和兒子兩個進程相互制約,爸爸進程執行完即往盤中放入蘋果后,兒子進程才能執行即吃蘋果。因此該問題為進程間的同步問題。
解:semaphore ?S_PlateNum; ?// 盤子容量,初值為1
semaphore ?S_AppleNum; ? // 蘋果數量,初值為0
void ?father( ) ? ? ? ? ? ? ? ?// 父親進程
{
? ? while(1)
? ? {
? ? ? ? P(S_PlateNum);
? ? ? ? 往盤子中放入一個蘋果;
? ? ? ? V(S_AppleNum);
? ? }?
}
void ?son( ) ? // 兒子進程
{
? ? while(1)
? ? {
? ? ? ? P(S_AppleNum);
? ? ? ? 從盤中取出蘋果;
? ? ? ? V(S_PlateNum);
? ? ? ? 吃蘋果;
? ? }?
}
另附用PV原語解決進程同步與互斥問題的例子:
經典IPC問題如:生產者-消費者,讀者-寫者,哲學家就餐,睡著的理發師等可參考相關教材。
一、兩個進程PA、PB通過兩個FIFO(先進先出)緩沖區隊列連接(如圖)
PA
PB
Q1
Q2
? ? PA從Q2取消息,處理后往Q1發消息,PB從Q1取消息,處理后往Q2發消息,每個緩沖區長度等于傳送消息長度. Q1隊列長度為n,Q2隊列長度為m. 假設開始時Q1中裝滿了消息,試用P、V操作解決上述進程間通訊問題。
解:// Q1隊列當中的空閑緩沖區個數,初值為0
semaphore ?S_BuffNum_Q1; ?
// Q2隊列當中的空閑緩沖區個數,初值為m?
semaphore ?S_BuffNum_Q2; ? ?
// Q1隊列當中的消息數量,初值為n?
semaphore ?S_MessageNum_Q1;
// Q2隊列當中的消息數量,初值為0?
semaphore ?S_MessageNum_Q2;
void ?PA( )
{
? ? ? ? while(1)
? ? ? ? {
? ? ? ? ? ? ? ? P(S_MessageNum_Q2);
? ? ? ? ? ? ? ? 從Q2當中取出一條消息;
? ? ? ? ? ? ? ? V(S_BuffNum_Q2);
? ? ? ? ? ? ? ? 處理消息;
? ? ? ? ? ? ? ? 生成新的消息;
? ? ? ? ? ? ? ? P(S_BuffNum_Q1);
? ? ? ? ? ? ? ? 把該消息發送到Q1當中;
? ? ? ? ? ? ? ? V(S_MessageNum_Q1);
? ? ? ? }?
}
void ?PB( )
{
? ? ? ? while(1)
? ? ? ? {
? ? ? ? ? ? ? ? P(S_MessageNum_Q1);
? ? ? ? ? ? ? ? 從Q1當中取出一條消息;
? ? ? ? ? ? ? ? V(S_BuffNum_Q1);
? ? ? ? ? ? ? ? 處理消息;
? ? ? ? ? ? ? ? 生成新的消息;
? ? ? ? ? ? ? ? P(S_BuffNum_Q2);
? ? ? ? ? ? ? ? 把該消息發送到Q2當中;
? ? ? ? ? ? ? ? V(S_MessageNum_Q2);
? ? ? ? }?
}
?
二、《操作系統》課程的期末考試即將舉行,假設把學生和監考老師都看作進程,學生有N人,教師1人??紙鲩T口每次只能進出一個人,進考場的原則是先來先進。當N個學生都進入了考場后,教師才能發卷子。學生交卷后即可離開考場,而教師要等收上來全部卷子并封裝卷子后才能離開考場。
(1)問共需設置幾個進程?
(2)請用P、V操作解決上述問題中的同步和互斥關系。
解:semaphore ?S_Door; ? ? ? ? ?// 能否進出門,初值1
semaphore ?S_StudentReady; ? ?// 學生是否到齊,初值為0
semaphore ?S_ExamBegin; ? // 開始考試,初值為0
semaphore ?S_ExamOver; ? ?// 考試結束,初值為0
int ?nStudentNum = 0; ? ? ? ? ?// 學生數目
semaphore ?S_Mutex1 ? ? ? ? //互斥信號量,初值為1
int ?nPaperNum = 0; ? ? ? // 已交的卷子數目
semaphore ?S_Mutex2 ? ? ? ? //互斥信號量,初值為1
void ?student( )
{
? ? ? ? P(S_Door);
? ? ? ? 進門;
? ? ? ? V(S_Door);
? ? ? ? P(S_Mutex1);
? ? ? ? nStudentNum ++; ? ? ? ? // 增加學生的個數
? ? ? ? if(nStudentNum == N) ?V(S_StudentReady);
? ? ? ? V(S_Mutex1);
? ? ? ? P(S_ExamBegin); ? ? ? ? // 等老師宣布考試開始
? ? ? ? 考試中…
? ? ? ? 交卷;
P(S_Mutex2);
? ? ? ? nPaperNum ++; ? ? ?// 增加試卷的份數
? ? ? ? if(nPaperNum == N) ?V(S_ExamOver);
? ? ? ? V(S_Mutex2);
? ? ? ? P(S_Door);
? ? ? ? 出門;
? ? ? ? V(S_Door);
}
void ?teacher( )
{
? ? ? ? P(S_Door);
? ? ? ? 進門;
? ? ? ? V(S_Door);
? ? ? ? P(S_StudentReady);//等待最后一個學生來喚醒
? ? ? ? 發卷子;
? ? ? ? for(i = 1; i <= N; i++) ? ?V(S_ExamBegin);
? ? ? ? P(S_ExamOver); ? ? ? ? // 等待考試結束
? ? ? ? 封裝試卷;
? ? ? ? P(S_Door);
? ? ? ? 出門;
? ? ? ? V(S_Door);
}
?
三、某商店有兩種食品A和B,最大數量均為m個。 該商店將A、B兩種食品搭配出售,每次各取一個。為避免食品變質,遵循先到食品先出售的原則。有兩個食品公司分別不斷地供應A、B兩種食品(每次一個)。為保證正常銷售,當某種食品的數量比另一種的數量超過k(k個時,暫停對數量大的食品進貨,補充數量少的食品。
(1) 問共需設置幾個進程?
(2) 用P、V操作解決上述問題中的同步互斥關系。
解:semaphore ?S_BuffNum_A; ?//A的緩沖區個數, 初值m
semaphore ?S_Num_A; ? ? ? ? ?// A的個數,初值為0
semaphore ?S_BuffNum_B; ?//B的緩沖區個數, 初值m
semaphore ?S_Num_B; ? ? ? ? ?// B的個數,初值為0
void ?Shop( )
{
? ? ? ? while(1)
? ? ? ? {
? ? ? ? ? ? ? ? P(S_Num_A);
? ? ? ? ? ? ? ? P(S_Num_B);
? ? ? ? ? ? ? ? 分別取出A、B食品各一個;
? ? ? ? ? ? ? ? V(S_BuffNum_A);
? ? ? ? ? ? ? ? V(S_BuffNum_A);
? ? ? ? ? ? ? ? 搭配地銷售這一對食品;
? ? ? ? }?
}
// “A食品加1,而B食品不變”這種情形允許出現的次數(許可證的數量),其值等于//k-(A-B),初值為k
semaphore ?S_A_B;
// “B食品加1,而A食品不變”這種情形允許出現的次數(許可證的數量),其值等于//k-(B-A),初值為k
semaphore ?S_B_A;
void ?Producer_A ( )
{
? ? ? ? while(1)
? ? ? ? {
? ? ? ? ? ? ? ? 生產一個A食品;
? ? ? ? ? ? ? ? P(S_BuffNum_A);
? ? ? ? ? ? ? ? P(S_A_B);
? ? ? ? ? ? ? ? 向商店提供一個A食品;
? ? ? ? ? ? ? ? V(S_Num_A);
? ? ? ? ? ? ? ? V(S_B_A);
? ? ? ? }?
}
void ?Producer_B ( )
{
? ? ? ? while(1)
? ? ? ? {
? ? ? ? ? ? ? ? 生產一個B食品;
? ? ? ? ? ? ? ? P(S_BuffNum_B);
? ? ? ? ? ? ? ? P(S_B_A);
? ? ? ? ? ? ? ? 向商店提供一個B食品;
? ? ? ? ? ? ? ? V(S_Num_B);
? ? ? ? ? ? ? ? V(S_A_B);
? ? ? ? }?
}
四:在一棟學生公寓里,只有一間浴室,而且這間浴室非常小,每一次只能容納一個人。公寓里既住著男生也住著女生,他們不得不分享這間浴室。因此,樓長制定了以下的浴室使用規則:(1)每一次只能有一個人在使用;(2)女生的優先級要高于男生,即如果同時有男生和女生在等待使用浴室,則女生優先;(3)對于相同性別的人來說,采用先來先使用的原則。
假設:
(1)當一個男生想要使用浴室時,他會去執行一個函數boy_wants_to_use_bathroom,當他離開浴室時,也會去執行另外一個函數boy_leaves_bathroom;
(2)當一個女生想要使用浴室時,會去執行函數girl_wants_to_use_bathroom,當她離開時, 也會執行函數girl_leaves_bathroom;
問題:請用信號量和P、V操作來實現這四個函數(初始狀態:浴室是空的)。
解:信號量的定義:
semaphore ?S_mutex; ? ? // 互斥信號量,初值均為1
semaphore ?S_boys; // 男生等待隊列,初值為0
semaphore ?S_girls; ? // 女生等待隊列,初值為0
普通變量的定義:
int ?boys_waiting = 0; ? ? // 正在等待的男生數;
int ?girls_waiting = 0; // 正在等待的女生數;
int ?using = 0; ? ? ?// 當前是否有人在使用浴室;
void ?boy_wants_to_use_bathroom ( )
{
? ? ? ? P(S_mutex);
? ? ? ? if((using == 0) && (girls_waiting == 0))
? ? ? ? ?{
? ? ? ? ? ? ? ? using ?= ?1;
? ? ? ? ? ? ? ? V(S_mutex);
? ? ? ? ?}
? ? ? ? else
? ? ? ? ?{
? ? ? ? ? ? ? ? boys_waiting ++;
? ? ? ? ? ? ? ? V(S_mutex);
? ? ? ? ? ? ? ? P(S_boys);
? ? ? ? ?}
}
void ?boy_leaves_bathroom ( )
{
? ? ? ? P(S_mutex);
? ? ? ? if(girls_waiting ?> ?0) ?// 優先喚醒女生
? ? ? ? ?{
? ? ? ? ? ? ? ? girls_waiting --;
? ? ? ? ? ? ? ? V(S_girls);
? ? ? ? ?}
? ? ? ? else ?if(boys_waiting ?> ?0)
? ? ? ? ?{
? ? ? ? ? ? ? ? boys_waiting --;
? ? ? ? ? ? ? ? V(S_ boys);
? ? ? ? ?}
? ? ? ? else ? ?using ?= ?0; ? ? ? ? // 無人在等待
? ? ? ? V(S_mutex);
}
void ?girl_wants_to_use_bathroom ( )
{
? ? ? ? P(S_mutex);
? ? ? ? if(using == 0)
? ? ? ? ?{
? ? ? ? ? ? ? ? using ?= ?1;
? ? ? ? ? ? ? ? V(S_mutex);
? ? ? ? ?}
? ? ? ? else
? ? ? ? ?{
? ? ? ? ? ? ? ? girls_waiting ++;
? ? ? ? ? ? ? ? V(S_mutex);
? ? ? ? ? ? ? ? P(S_girls);
? ? ? ? ?}
}
void ?girl_leaves_bathroom ( )
{
? ? ? ? P(S_mutex);
? ? ? ? if(girls_waiting ?> ?0) ?// 優先喚醒女生
? ? ? ? ?{
? ? ? ? ? ? ? ? girls_waiting --;
? ? ? ? ? ? ? ? V(S_girls);
? ? ? ? ?}
? ? ? ? else ?if(boys_waiting ?> ?0)
? ? ? ? ?{
? ? ? ? ? ? ? ? boys_waiting --;
? ? ? ? ? ? ? ? V(S_ boys);
? ? ? ? ?}
? ? ? ? else ? ?using ?= ?0; ? ? ? ? // 無人在等待
? ? ? ? V(S_mutex);
}
========
實驗四 簡單的PV操作
http://www.cnblogs.com/amzinghui/p/5607219.html一、 ? ? ? ?實驗目的
1.掌握臨界區的概念及臨界區的設計原則;
2.掌握信號量的概念、PV操作的含義以及應用PV操作實現進程的同步與互斥;
3.分析進程爭用資源的現象,學習解決進程互斥的方法。
二、 ? ? ? ?實驗內容和要求
分析進程的同步與互斥現象,編程實現經典的進程同步問題——生產者消費者問題的模擬
生產者--消費者問題表述:
有一環形緩沖池,包含n個緩沖區(0~n-1)。
有兩類進程:一組生產者進程和一組消費者進程,生產者進程向空的緩沖區中放產品,消費者進程從滿的緩沖區中取走產品。
所有進程必須對緩沖區進行互斥的訪問。
生產者不能向滿緩沖區寫數據,消費者不能從空緩沖區取數據,即生產者與消費者必須同步。
計算機系統中對資源的分配與釋放過程:計算機系統中的每個進程都可以消費或生產某類資源。當系統中某一進程使用某一資源時,可以看作是消耗,且該進程稱為消費者。而當某個進程釋放資源時,則它就相當一個生產者。
定義生產者消費者問題中的各數據結構,并初始化。
信號量,初值。
編寫PV操作。
編寫生產者與消費者程序,利用信號量及其PV操作,實現生產者與消費者之間的同步與互斥。
模擬顯示生產者與消費者同步與互斥的效果。
三、 實驗方法、步驟及結果測試
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#define N 50
typedef struct process
{
? ?int i;
}P;
P a[N];
int workingtime=0;
void main(){
int a=0,b;
int flag=1;
int p=0,v=0;
int n,i;
printf("你想要貨架上有多少空間?\n");
scanf("%d",&n);
while(flag==1)
{
srand(time(NULL));
b=rand()%2+1;
if(b==1)
{
? ?if(a<5&&p==0&&v==0)
? ?{
? ? ? p++;
? ? ? v++;
? ? ? ? ? a++;
? ?printf("放置商品\n");
? ?p--;
? ? ? v--;
? ?}
else{
printf("無法放置更多的商品\n");
} ?
??
}
else
{
if(a>0&&p==0&&v==0)
{
? ? ? p++;
? ? ? v++;
? ?a--;
? ?printf("商品已被消費\n");
? ? ? p--;
? ? ? v--;
}
else{
printf("現在貨架上并沒有商品\n");
} ?
?
}
printf("繼續請輸1,退出請輸2\n");
scanf("%d",&flag);
?
}
}
四、 實驗總結
此次實驗除了用c語言實現PV操作的問題上有點困難,只能在顯示效果上模擬,并且成功完成了試驗要求。
========
總結
以上是生活随笔為你收集整理的操作系统pv操作学习总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 操作系统机制学习总结
- 下一篇: SQL CTE学习总结