您當前的位置:首頁 > 攝影

學會程序同步,有這一篇就夠了

作者:由 一禪 發表于 攝影時間:2020-12-06

同步速度什麼意思

為什麼要有程序同步

直接談程序同步的概念有點抽象,我們先聊一聊為什麼要有程序同步機制。 我們的計算機系統剛開始是單道批處理系統,意思就是同一時間段內只能執行一個程式,這個程式執行完,才能執行另一個程式,這樣就會導致執行效率太低,系統中的資源得不到充分的利用。 怎麼解決呢,就發明了多道批處理系統,多道程式併發執行,這樣大大提高了系統資源的利用率。 但是這種系統就會產生一些問題,比如有的資源,比如顯示器,cpu,同一時間肯定只能一個程式使用,多個程式肯定不能同時使用顯示器,這就是

「互斥關係」

,另外,有的兩個程序間存在這樣的制約關係:A程式的輸出是B程式的輸入,這是

「同步關係」

,為了解決這些問題,我們引入了程序同步機制。

程序同步的方法

怎麼用程序同步的方法解決上述問題呢,其中一個方法就是訊號量機制。

訊號量機制

訊號量機制是由荷蘭的dijkstra發明的,有三種訊號量機制,分別是

「整型訊號量」

「結構體型訊號量」

「AND型訊號量」

「整型訊號量」

說白了就是用一個整數來進行管理,這個整數代表資源的數目,眾所周知,對資源的操作有兩種,一種是使用,一種是釋放。 他們分別對應兩個函式:wait和signal

wait(S){

while(S<=0);

S——;

}

signal(S){

S++;

}

wait方法的意思就是首先看資源可不可以用,如果不可以用,也就是S<=0,它會一直等下去,直到S成為一個正數,然後S自減;signal的意思是使用完資源後釋放資源,S自增。

「結構體型訊號量」

為什麼整型訊號量用的好好的,要造一個結構體型訊號量呢? 因為整型訊號量有個問題:我們會發現當S<=0的時候,會一直執行迴圈,也就是程序會處於忙等的狀態。 我們要解決忙等,也就是要讓程序符合“讓權等待”,就是要在程序無法使用資源的時候,釋放處理機。 那麼問題就來了,該讓哪個程序訪問臨界資源呢? 我們可以使用一個連結串列來解決這個問題。 所以我們就用一個結構體來描述資源,這個結構體長這樣:

typedef struct{

int value;

struct process_control_block *list;

}semaphore;

這個結構體裡邊有兩個變數,一個是value,用來記錄資源的個數,下邊這個是指標,指向下一個要使用臨界資源的程序。 所以之前的使用和釋放資源的函式就變成了這樣:

wait(semaphore *S){

S->value——;

if(S->value<0) block(S->list);

}

signal(semaphore *S){

s->value++;

if(S->value<=0) wakeup(S->list);

}

使用訊號量機制解決問題

上邊咱們只是簡單介紹了一下訊號量機制,但別忘了咋們是要解決互斥關係和同步關係這兩個問題的。

「實現互斥關係」

假設兩個程序PA,PB具有互斥關係,也就是他們倆要使用一個臨界資源,怎麼做呢,我們設定一個mutex訊號量,初值設為1,這樣的話剛開始兩個程序都能使用,他們使用的時候,先wait,wait完自然要讓mutex-1,這樣mutex為0,另一個就不能用了,使用完以後signal(釋放),mutex重新變成1,另一個程序依然可以使用該臨界資源。

semaphore mutex=1;

PA(){

while(1){

wait(mutex);

臨界區

signal(mutex);

剩餘區

}

}

PB(){

while(1){

wait(mutex);

臨界區

signal(mutex);

剩餘區

}

}

「實現前驅關係」

假設P1和P2有前驅關係,P1執行完,P2才能執行,那麼怎麼實現呢? 可以設定一個公共的訊號量S,初值設為0

程序P1中:S1;signal(S);

程序P2中:wait(S);S2;

這個是什麼意思呢,就是先執行P1的語句,然後釋放S,也就是S++,這樣當P2執行wait的時候才可以執行,否則,不執行signal的話,S就為0,P2也無法執行,這樣就實現了P1和P2的前驅關係。

標簽: 訊號量  WAIT  mutex  signal  程序同步