多執行緒中的鎖系統 一 基礎用法

2022-02-01 22:58:40 字數 4232 閱讀 6133

一:lock、monitor

1:基礎。

2: 作用域。

3:字串鎖。

4:monitor使用

二:mutex

三:semaphore

四:總結

lock是monitor語法糖簡化寫法。lock在il會生成monitor。

//

*****=example 1*****

string obj = "

helloworld";

lock

(obj)

//lock il會編譯成如下寫法

bool isgetlock = false

; monitor.enter(obj,

refisgetlock);

try

finally

}

isgetlock引數是framework  4.0後新加的。 為了使程式在所有情況下都能夠確定,是否有必要釋放鎖。例: monitor.enter拿不到鎖

monitor.enter 是可以鎖值型別的。鎖時會裝箱成新物件,所以無法做到執行緒同步。

一:lock是只能在程序內鎖,不能跨程序。走的是混合構造,先自旋再轉成核心構造。

二:關於對type型別的鎖。如下:

//

*****=example 2*****

new thread(new threadstart(() =>

})).start();

thread.sleep(

1000

);

lock(typeof(int

))

執行結果如下:

跨應用程式域邊界或遠端訪問時需要繼承marshalbyrefobject

/// public

class

locktest : marshalbyrefobject}}

執行結果如下:

第乙個例子說明,在同程序同域,不同執行緒下,鎖type int,其實鎖的是同乙個int物件。所以要慎用。

第二個例子,這裡就簡單說下。

c: 而每個程式域都有屬於自己的託管堆。託管堆中最重要的是gc heap和loader heap。gc heap用於引用型別例項的儲存,生命週期管理和垃圾**。loader heap儲存型別系統,如methodtable,資料結構等,loader heap生命週期不受gc管理,跟程式域解除安裝有關。

所以共享域中loader heap mscorlib.dll中的int例項會一直保留著,直到程序結束。單個程式域解除安裝也不受影響。作用域很大有沒有!!!

這時第二個例子也很容易理解了。 鎖int例項是跨程式域的,mscorlib中的基礎型別都是這樣。 極容易造成死鎖,慎用。  而自定義型別則會載入到自己的程式域,不會影響別人。

//*****=example 4*****

stringstr1 ="mushroom";

stringstr2 ="mushroom";

varresult1 =object.referenceequals(str1, str2);

varresult2 =object.referenceequals(str1,"mushroom");

console.writeline(result1 +"-"+ result2);

/* output

* true-true

*/

正式由於c#中字串的這種特性,所以字串是在多執行緒下是不會被修改的,唯讀的。它存在於systemdomain域中managed heap中的乙個hash table中。key為string本身,value為string物件的位址。

簡單介紹下wait,pulse,pulseall的用法,已加注釋。

static

string str = "

mushroom";

static

void main(string

args)

finally

}}).start();

thread.sleep(

1000

);

new thread(() =>

finally

}}).start();

console.readline();

lock是不能跨程序鎖的。 mutex作用和lock類似,但是它能跨程序鎖資源(走的是windows核心構造)。 我們來看個例子

static

bool createnew = false

;

//第乙個引數 是否應擁有互斥體的初始所屬權。即createnew true時,mutex預設獲得處理訊號

//第二個是名字,第三個是否成功。

public

static mutex mutex = new mutex(true, "

mushroom.mutex

", out

createnew);

static

void main(string

args)

finally

}//waitone 函式作用是阻止當前執行緒,直到拿到收到其他例項釋放的處理訊號。

//第乙個引數是等待超時時間,第二個是否退出上下文同步域。

else

if (mutex.waitone(10000,false))//

finally

}else

//如果沒有發現處理訊號

}static

void

run()

我們順序起a  b例項測試下。   a首先拿到鎖,輸出 例項1 。   b在等待, 如果10秒內a釋放,b拿到執行run()。  超時後輸出  已經有例項了。

這裡注意的是第乙個拿到處理訊號 的例項,已經拿到鎖了。不需要再waitone。  否則報異常。  

即訊號量,我們可以把它理解為公升級版的mutex。mutex對乙個資源進行鎖,semaphore則是對多個資源進行加鎖。

semaphore是由windows核心維持乙個int32變數的執行緒計數器,執行緒每呼叫一次、計數器減

一、釋放後對應加一, 超出的執行緒則排隊等候。

走的是核心構造,所以semaphore也是可以跨程序的。

static

void main(string

args)

).start(i);

}console.readline();

}

mutex、semaphore  需要由託管**轉成本地使用者模式**、再轉換為本地核心**。  

反之同樣,效能會有一定的損耗,僅在需要跨程序的場景使用。

參考: 

多執行緒中的鎖系統 一 基礎用法

平常在多執行緒開發中,總避免不了執行緒同步。本篇對net多執行緒中的鎖系統做個簡單描述。lock monitor 作用域範圍 字串鎖monitor的用法 mutex semaphore 總結lock是monitor語法糖簡化寫法,lock在il會生成monitor。example 1 string ...

python多執行緒的鎖用法

鎖機制 在了解鎖機制前,我們先來看一下下面這個例子 使用多執行緒進行加法運算 import threading 定義全域性變數value value 0 定義加法執行緒函式 def add value global value for x in range 1000000 value 1 print...

多執行緒中的鎖

導致死鎖的原因 有兩個或多個執行緒需要在幾個共享物件上獲取鎖,這可能會導致死鎖。thread1 object1 object2 thread2 object2 object1 死鎖的四個條件 1.互斥條件 2.不可剝奪條件 3.請求與保持條件 4.迴圈等待條件 解決方式 1.避免滿足產生死鎖的四個條...