平常在多執行緒開發中,總避免不了執行緒同步。本篇對net多執行緒中的鎖系統做個簡單描述。
lock、monitor
作用域範圍
字串鎖monitor的用法
mutex
semaphore
總結lock是monitor語法糖簡化寫法,lock在il會生成monitor。
//isgetlock引數是framework 4.0後新加的。 為了使程式在所有情況下都能夠確定,是否有必要釋放鎖。例: monitor.enter拿不到鎖*****=example 1*****
string obj = "
helloworld";
lock
(obj)
//lock il會編譯成如下寫法
bool isgetlock = false
; monitor.enter(obj,
refisgetlock);
try
finally
}
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*****正是由於c#中字串的這種特性,所以字串是在多執行緒下是不會被修改的,唯讀的。它存在於systemdomain域中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
*/
managed heap中的乙個hash table中。其中
key為string本身,value為string物件的位址。
簡單介紹下wait,pulse,pulseall的用法,已加注釋。
staticlock是不能跨程序鎖的。 mutex作用和lock類似,但是它能跨程序鎖資源(走的是windows核心構造),如例子:string str = "
mushroom";
static
void main(string
args)
finally
}}).start();
thread.sleep(
1000
);
new thread(() =>
finally
}}).start();
console.readline();
static順序啟動a b例項測試下。a首先拿到鎖,輸出 例項1 。b在等待, 如果10秒內a釋放,b拿到執行run()。超時後輸出"已經有例項了"。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()
這裡注意的是第乙個拿到處理訊號 的例項,已經拿到鎖了。不需要再waitone。 否則報異常。
即訊號量,我們可以把它理解為公升級版的mutex。mutex對乙個資源進行鎖,semaphore則是對多個資源進行加鎖。
semaphore是由windows核心維持乙個int32變數的執行緒計數器,執行緒每呼叫一次、計數器減
一、釋放後對應加一, 超出的執行緒則排隊等候。
走的是核心構造,所以semaphore也是可以跨程序的。
staticmutex、semaphore 需要先把託管**轉成本地使用者模式**、再轉換成本地核心**。void main(string
args)
).start(i);
}console.readline();
}
當釋放後需要重新轉換成託管**,效能會有一定的損耗,所以盡量在需要跨程序的場景再使用。
參考
多執行緒中的鎖系統 一 基礎用法
一 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.避免滿足產生死鎖的四個條...