1. 程式人生 > >pv操作及訊號量實用例項詳解

pv操作及訊號量實用例項詳解

學習PV操作之前,我們首先來了解兩個很基礎的概念:

同步、互斥:

同步:其實說同步還不如說”協作“,就是我們的目標只有一個,我們奔著同一個目標去的,都是在大家的努力下共同完成這麼一件事情。還是比較容易理解的吧。不見得太難。

互斥:借用別人的一句話“千軍萬馬過獨木橋”,很通俗的一句話,就把咱們這個概念表達的淋漓盡致,就好比有一個大部隊來到獨木橋這,但是必須排好隊,一個一個來;其實現實生活中,還有一個很好的例子可以說明這個互斥的概念,比如印表機,印表機這個工具就非常好的體現了互斥的概念,印表機一旦被別人佔用了,那無亂你有多著急,都只能等著,對吧。

其實借用別人的話或者資料或者工具來讓咱們的學習更加輕鬆,為咱們的學習加把油,何樂而不為呢?這就是我要說的“站在巨人的肩膀上”來看問題,許多問題就變得輕鬆起來;這是一種思想,旨在為咱們的學習加把油~這是題外話,但是更重要的是一種思想,很值得學習。

我們接下來還繼續看一下一張同步的圖:

這張圖也特別的形象具體,我們具體來看看這張圖,A倉庫有貨物,然後我們需要把貨物搬運到B倉庫,由搬運工甲和搬運工乙來完成這個過程;那麼他們的目標就只有一個,就是把貨物從A搬到B去,共同奔著這個方向去發展,所以我們說這是一個同步的問題。

臨界資源:就是咱們剛剛說的互斥,諸程序間需要互斥方式對其進行共享資源,如印表機、光碟機等。

臨界區:就是程序訪問臨界資源的那段程式碼。

講了那麼久,我們才引入了PV操作,看來這個PV操作還是挺有意思的。

PV操作:解決互斥和同步的問題。PV操作是分開來看的:

P操作:使S=S-1,若S>=0,則該程序繼續執行,否則該程序排入等待佇列。

V操作:使S=S+1,若S>0,喚醒等待佇列中的一個程序。

這樣理解不太好理解,咱們還是來看例子吧:

接下來,我們來看一個與咱們生活很貼切的問題:生產者——消費者問題:

我們還是一樣,通過圖片來分析問題:

這是一個著名的同步問題,雖然生產者程序和消費者程序都是非同步方式執行的,但它們之間必須保持同步,即不允許消費者程序到一個空緩衝區去取產品,也不允許生產者程序向一個已裝滿產品且尚未被取走的緩衝區中投放產品。這是一個單緩衝區情況。那麼這個單緩衝區的PV操作,應該是怎樣的呢?我們來看看:

我們分析分析,很容易的發現這個流程,前提是S1初值為1,S2初值為0。我們需要記住P操作減1,V操作加1,然後這個分析就變得易如反掌了,我們先對初值進行一下說明:

a、我們把S1的初值設為1:是說明緩衝區還有一個空間可以使用,對於生產者而言,每一個緩衝區的一個空間就是一個資源,也就是說,一開始執行的時候,就允許生產者投放一個產品到緩衝區,

b、然後投放到緩衝區之後,我們來看消費者程序,P(S2):首先我們要程序一個判斷,判斷緩衝區中是否有產品,對消費者而言,緩衝區中有產品,就代表有一個資源可以使用,但是最初狀態那個緩衝區中是沒有資源的,所以S2的初值應該是為0的。

我們剛才都提到了資源的問題,就是訊號量的一個值應該是表示資源的數量,但是就消費者和生產者而言,對於他們的資源是不同的,概念是不同的,生產者:緩衝區有多少個空格,就有多少個資源;而對消費者來說,緩衝區有多少個滿的格,就有多少個資源,是剛好是相反,所以說,就是這麼相反,所以當消費者從緩衝區取出一個產品之後,對於生產者而已,就多了一個資源。

其實這個過程就是這樣的。

1、生產者:P(S1),那麼P(S1),S1=S1-1,得到P(S1=0)這個程序還能進行,那麼生產者把一個產品投放到緩衝區。

2、V(S2),S2=S2+1,S2初值為0,所以S2=S2+1>0,那麼就激活了P(S2),那麼消費者就能取出一個產品。

4、消費產品:消費產品之前,還有一個V(S1),就激活了P(S1),讓生產者繼續投放產品到緩衝區。

特別簡單吧,這是單緩衝區分析。

我們接下來看一個相對來說,有點複雜一點點的,多緩衝區的,其實也一樣一樣的,繼續:

我們還是分析一樣的問題,生產者、消費者問題:

對應的PV操作應該是這樣的:

有一點區別,就是要引用互斥的概念,因為緩衝區是一個臨界資源,它始終只能有一個程序對其進行操作,所以我們就可以用一個互斥訊號量來完成這一點,所以當某一個程序要使用到緩衝區之前,我們就進行以下判斷,判斷這個緩衝區現在是不是空閒呢?是不是有生產者或者消費者的程序在使用這個這個緩衝區呢?如果有,mute的初值為1,當有人使用這個緩衝區的時候,這個mute的值就由1變為0,這時,第二個程序向再來操作這個緩衝區,就不可能了,就會被阻塞,當第一個程序使用完緩衝區

公交車司機與售票員的問題:

我們來分析這個過程,我們把S1和S2的初值都設為0。我們來分析分析:

1、P(S1):S1=S1-1=-1,那麼司機程序就被暫停,等會售票員程序,售票員關車門。

2、V(S1):S1=S1+1=0,激活了司機程序,那麼司機就開始啟動車輛、正常行駛、到站停車,當然售票員也有可能同時在售票。

3、P(S2):S2=S2-1,售票員在售票之後的程序就被暫停,等待司機程序。這樣就避免了售票員售票之後就開車門了。因為這是不允許的。

4、V(S2):S2=S2+1,司機到站停車之後,就激活了售票員P(S2)的程序,那麼售票員就程序 開車門、上下客的操作。

那麼這個程序就完成了。

感謝你的閱讀!