一文帶你了解.Net基于Threading.Mutex實現(xiàn)互斥鎖
本文主要講解.Net基于Threading.Mutex實現(xiàn)互斥鎖
基礎(chǔ)互斥鎖實現(xiàn)
基礎(chǔ)概念:和自旋鎖一樣,操作系統(tǒng)提供的互斥鎖內(nèi)部有一個數(shù)值表示鎖是否已經(jīng)被獲取,不同的是當獲取鎖失敗的時候,它不會反復進行重試,而且讓線程進入等待狀態(tài),并把線程對象添加到鎖關(guān)聯(lián)的隊列中,另一個線程釋放鎖時會檢查隊列中是否有線程對象,如果有則通知操作系統(tǒng)喚醒該線程,因為獲取鎖的線程對象沒有進行運行,即使鎖長時間不釋放也不會消耗CPU資源,但讓線程進入等待狀態(tài)和從等待狀態(tài)喚醒的時間比自旋鎖重試的納秒級時間要長
windows和linux的區(qū)別
在windows系統(tǒng)上互斥鎖通過CreateMuteEx函數(shù)創(chuàng)建,獲取鎖時將調(diào)用WaitForMultipleObjectsEx函數(shù),釋放鎖將調(diào)用ReleaseMutex函數(shù),線程進入等待狀態(tài)和喚醒由系統(tǒng)操作
在Linux上互斥鎖對象由NetCore的內(nèi)部接口模擬實現(xiàn),結(jié)果包含鎖的狀態(tài)值以及等待線程隊列,每個托管線程都會關(guān)聯(lián)一個pthread_mutex_t對象和一個pthread_cond_t對象,這兩個對象友pthread類庫提供,獲取鎖失敗線程會調(diào)價到隊列pthread_cond_wait函數(shù)等待,另一個線程釋放鎖時看到隊列中有線程則調(diào)用pthread_cond_signal函數(shù)喚醒。
基礎(chǔ)互斥鎖代碼實現(xiàn)
public static class MutexDemo
{
private static readonly Mutex _lock = new Mutex(false, null);
private static int _counterA = 0;
private static int _counterB = 0;
public static void IncrementCounters()
{
//獲取鎖
_lock.WaitOne();
try
{
++_counterA;
++_counterB;
}
finally
{
//釋放鎖
_lock.ReleaseMutex();
}
}
public static void GetCounters(out int counterA, out int counterB)
{
_lock.WaitOne();
try
{
counterA = _counterA;
counterB = _counterB;
}
finally
{
//釋放鎖
_lock.ReleaseMutex();
}
}
}
互斥鎖(遞歸鎖)
基礎(chǔ)概念:Mutex提供的鎖可重入,已經(jīng)獲取鎖的線程可以再次執(zhí)行獲取鎖的操作,但釋放鎖的操作也要執(zhí)行對應的相同次數(shù),可重入的鎖又叫遞歸鎖。
實現(xiàn)原理:遞歸鎖內(nèi)部使用一個計數(shù)器記錄進入次數(shù),同一個線程每獲取一次就加1,釋放一次就減1,減1后如果計算器為0就執(zhí)行真正的釋放操作。遞歸鎖在單個函數(shù)中使用沒有意義,一般嵌套在多個函數(shù)中
代碼實現(xiàn)
public static class MutexRecursionDemo
{
private static Mutex _lock = new Mutex(false, null);
private static int _counterA = 0;
private static int _counterB = 0;
public static void IncrementCountersA()
{
//獲取鎖
_lock.WaitOne();
try
{
++_counterA;
}
finally
{
//釋放鎖
_lock.ReleaseMutex();
}
}
public static void IncrementCountersB()
{
//獲取鎖
_lock.WaitOne();
try
{
++_counterB;
}
finally
{
//釋放鎖
_lock.ReleaseMutex();
}
}
public static void IncrementCounters()
{
//獲取鎖
_lock.WaitOne();
try
{
IncrementCountersA();
IncrementCountersB();
}
finally
{
//釋放鎖
_lock.ReleaseMutex();
}
}
public static void GetCounters(out int counterA, out int counterB)
{
_lock.WaitOne();
try
{
counterA = _counterA;
counterB = _counterB;
}
finally
{
//釋放鎖
_lock.ReleaseMutex();
}
}
}
互斥鎖(跨進程使用)
基礎(chǔ)概念:Mutex支持夸進程使用,創(chuàng)建是通過構(gòu)造函數(shù)的第二個參數(shù)name傳入名稱,名稱以Walterlv.Mutex開始時同一個用戶的進程共享擁有此名稱的鎖,如果一個進程中獲取了鎖,那么在釋放該鎖前另一個進程獲取同樣名稱的鎖需要等待,如果進程獲取了鎖,但是在退出之前沒有調(diào)用釋放鎖的方法,那么鎖會被自動釋放,其他當前正在等待鎖的京城會受到AbandonedMuteException異常。
linux實現(xiàn)方式是通過臨時文件的方式實現(xiàn)
實現(xiàn)代碼
public static class MutexDemo
{
private static Mutex _lock = new Mutex(false, @"Walterlv.Mutex");
private static int _counterA = 0;
private static int _counterB = 0;
public static void IncrementCounters()
{
//獲取鎖
_lock.WaitOne();
try
{
++_counterA;
++_counterB;
}
finally
{
//釋放鎖
_lock.ReleaseMutex();
}
}
public static void GetCounters(out int counterA, out int counterB)
{
_lock.WaitOne();
try
{
counterA = _counterA;
counterB = _counterB;
}
finally
{
//釋放鎖
_lock.ReleaseMutex();
}
}
}
以上代碼只需要復制一份,在多個程序中啟動,調(diào)用MutexDemo.IncrementCounters()則可以看到效果
到此這篇關(guān)于一文帶你了解.Net基于Threading.Mutex實現(xiàn)互斥鎖的文章就介紹到這了,更多相關(guān).Net 互斥鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Asp.net MVC中Razor常見的問題與解決方法總結(jié)
這篇文章主要給大家介紹了關(guān)于Asp.net MVC中Razor常見的問題與解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面跟著小編來一起學習學習吧。2017-08-08
asp.net使用ODP即oracle連接方式的的防注入登錄驗證程序
這篇文章主要介紹了asp.net使用ODP即oracle連接方式的的防注入登錄驗證程序,需要的朋友可以參考下2014-05-05
XmlReader 讀取器讀取內(nèi)存流 MemoryStream 的注意事項
XmlReader 讀取器讀取內(nèi)存流 MemoryStream 的注意事項...2007-04-04
asp.net mvc CodeFirst模式數(shù)據(jù)庫遷移步驟詳解
這篇文章主要為大家詳細介紹了asp.net mvc CodeFirst模式數(shù)據(jù)庫遷移步驟,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-10-10
ASP.NET MVC 開發(fā)微信支付H5的實現(xiàn)示例(外置瀏覽器支付)
這篇文章主要介紹了ASP.NET MVC 開發(fā)微信支付H5的實現(xiàn)示例(外置瀏覽器支付),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-12-12
剖析ASP.NET MVC的DependencyResolver組件
這篇文章主要為大家剖析ASP.NET MVC的DependencyResolver組件,感興趣的小伙伴們可以參考一下2016-04-04
ASP.NET MVC3 實現(xiàn)全站重定向的簡單方法
這篇文章主要介紹了ASP.NET MVC3 實現(xiàn)全站重定向的簡單方法,有需要的朋友可以參考一下2014-01-01

