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

2022-01-17 12:49:17 字數 3865 閱讀 3776

平常在多執行緒開發中,總避免不了執行緒同步。本篇對net多執行緒中的鎖系統做個簡單描述。

lock、monitor

作用域範圍

字串鎖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

))

執行結果如下:

在看個例子:

//

*****=example 3*****

console.writeline(datetime.now);");

assembly.getexecutingassembly().fullname,

""); worker1.run();");

assembly.getexecutingassembly().fullname,

""); worker2.run();

//////

跨應用程式域邊界或遠端訪問時需要繼承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*****

string str1 = "mushroom";

string str2 = "mushroom";

var result1 = object.referenceequals(str1, str2);

var result2 = 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  需要先把託管**轉成本地使用者模式**、再轉換成本地核心**。  

當釋放後需要重新轉換成託管**,效能會有一定的損耗,所以盡量在需要跨程序的場景再使用。 

參考

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

一 lock monitor 1 基礎。2 作用域。3 字串鎖。4 monitor使用 二 mutex 三 semaphore 四 總結 lock是monitor語法糖簡化寫法。lock在il會生成monitor。example 1 string obj helloworld lock obj lo...

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.避免滿足產生死鎖的四個條...