程序同步與程序互斥
在多執行緒環境下,同步與互斥顯得格外重要,如果處理不好,會導致執行結果出現意想不到的錯誤。
同步:先看下面這張圖
執行緒p1,p2,p3合作完成一項任務,執行緒p2,p1可以併發進行,執行緒p3需要p1,p2都完成之後才能執行,這就是一個執行緒(或程序)同步問題。
臨界資源:為多個執行緒所共享的資源,同一時間段只能容許一個執行緒對其進行操作的資源。
臨界區:執行緒中,操作臨界資源的程式段。
互斥:同一時間段內,只能容許一個執行緒進入臨界區,對臨界資源進行操作。
實現執行緒同步與執行緒互斥有軟體方法和硬體方法,但是目前,軟體方法很少使用,因此,這裡我不涉及,主要講解訊號量機制(硬體方法)實現同步與互斥。
訊號量S的含義:S>=0 代表當前可以使用的資源數量
S<0. 代表當前等待佇列中執行緒數量
PV操作(不可被中斷):
P(S):{
S=S-1;
if(S<0){
資源不足,將執行緒放入等待佇列中
}
}
V(S):{
S=S+1;
if(S>=0){
從等待佇列中取出一個執行緒執行
}
}
P(S)代表申請一個資源,如果S>0則表示目前有可用資源,執行緒可以繼續執行,否則,將其放入等待佇列中。
V(S)代表釋放一個資源,如果等待佇列不為空,則從裡取出一個執行緒,讓其執行。
給大家講兩個例題來幫助大家理解。
就針對這幅圖,用訊號量實現三個執行緒的同步。程式碼如下:
//定義訊號量並附初值
semaphore S1=0 S2=0
p1:{
...
p1程式碼段執行
V(S1)
}
p2:{
...
p2程式碼段執行
V(S2)
}
p3:{
P(S1)
P(S2)
p3程式碼段執行
...
}
不知道大家都沒有弄懂,不懂的話,歡迎評論,我會定期檢視的,和大家交流。
例題二:生產者-消費者問題(很經典的執行緒同步問題)
問題描述:生產者消費者問題是一種同步問題的抽象描述。計算機系統中的每個程序都可以消費(使用)或生產(釋放)某類資源。這些資源可以是硬體資源,也可以是軟體資源。
當某一程序使用某一資源時,可以看作是消費,稱該程序為消費者。
而當某一程序釋放某一資源時,它就相當於生產者。
通過一個有界緩衝區可以把一群生產者p1,p2…,pm,和一群消費者Q1,Q2,…,Qn聯絡起來。只要緩衝區未滿,生產者就可以把產品送入緩衝區;只要緩衝區未空,消費者就可以從緩衝區中取走物品。如圖:
解答程式碼如下:
//定義訊號量
semaphore mutex=1,S1=n,S2=0
produce:{
P(S1)
P(mutex)
執行放入訊息程式碼
V(mutex)
V(S2)
}
consumer:{
P(S2)
P(mutex)
執行取出訊息程式碼
V(mutex)
V(S1)
}
我來對上述變數進行解釋一下,metux訊號量是為了實現對共享緩衝區實現互斥,同一時間段內只能有一個執行緒對其進行修改。S1訊號量表示空的緩衝區個數,S2表示非空緩衝區個數。
好吧,執行緒(或程序)的同步和互斥就講到這裡啦,其實就是要理解訊號量機制就可以了。