一文帶你了解.Net基于Threading.Mutex實(shí)現(xiàn)互斥鎖
本文主要講解.Net基于Threading.Mutex實(shí)現(xiàn)互斥鎖
基礎(chǔ)互斥鎖實(shí)現(xiàn)
基礎(chǔ)概念:和自旋鎖一樣,操作系統(tǒng)提供的互斥鎖內(nèi)部有一個(gè)數(shù)值表示鎖是否已經(jīng)被獲取,不同的是當(dāng)獲取鎖失敗的時(shí)候,它不會(huì)反復(fù)進(jìn)行重試,而且讓線程進(jìn)入等待狀態(tài),并把線程對(duì)象添加到鎖關(guān)聯(lián)的隊(duì)列中,另一個(gè)線程釋放鎖時(shí)會(huì)檢查隊(duì)列中是否有線程對(duì)象,如果有則通知操作系統(tǒng)喚醒該線程,因?yàn)楂@取鎖的線程對(duì)象沒(méi)有進(jìn)行運(yùn)行,即使鎖長(zhǎng)時(shí)間不釋放也不會(huì)消耗CPU資源,但讓線程進(jìn)入等待狀態(tài)和從等待狀態(tài)喚醒的時(shí)間比自旋鎖重試的納秒級(jí)時(shí)間要長(zhǎng)
windows和linux的區(qū)別
在windows系統(tǒng)上互斥鎖通過(guò)CreateMuteEx函數(shù)創(chuàng)建,獲取鎖時(shí)將調(diào)用WaitForMultipleObjectsEx函數(shù),釋放鎖將調(diào)用ReleaseMutex函數(shù),線程進(jìn)入等待狀態(tài)和喚醒由系統(tǒng)操作
在Linux上互斥鎖對(duì)象由NetCore的內(nèi)部接口模擬實(shí)現(xiàn),結(jié)果包含鎖的狀態(tài)值以及等待線程隊(duì)列,每個(gè)托管線程都會(huì)關(guān)聯(lián)一個(gè)pthread_mutex_t對(duì)象和一個(gè)pthread_cond_t對(duì)象,這兩個(gè)對(duì)象友pthread類庫(kù)提供,獲取鎖失敗線程會(huì)調(diào)價(jià)到隊(duì)列pthread_cond_wait函數(shù)等待,另一個(gè)線程釋放鎖時(shí)看到隊(duì)列中有線程則調(diào)用pthread_cond_signal函數(shù)喚醒。
基礎(chǔ)互斥鎖代碼實(shí)現(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í)行對(duì)應(yīng)的相同次數(shù),可重入的鎖又叫遞歸鎖。
實(shí)現(xiàn)原理:遞歸鎖內(nèi)部使用一個(gè)計(jì)數(shù)器記錄進(jìn)入次數(shù),同一個(gè)線程每獲取一次就加1,釋放一次就減1,減1后如果計(jì)算器為0就執(zhí)行真正的釋放操作。遞歸鎖在單個(gè)函數(shù)中使用沒(méi)有意義,一般嵌套在多個(gè)函數(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(); } } }
互斥鎖(跨進(jìn)程使用)
基礎(chǔ)概念:Mutex支持夸進(jìn)程使用,創(chuàng)建是通過(guò)構(gòu)造函數(shù)的第二個(gè)參數(shù)name傳入名稱,名稱以Walterlv.Mutex開(kāi)始時(shí)同一個(gè)用戶的進(jìn)程共享?yè)碛写嗣Q的鎖,如果一個(gè)進(jìn)程中獲取了鎖,那么在釋放該鎖前另一個(gè)進(jìn)程獲取同樣名稱的鎖需要等待,如果進(jìn)程獲取了鎖,但是在退出之前沒(méi)有調(diào)用釋放鎖的方法,那么鎖會(huì)被自動(dòng)釋放,其他當(dāng)前正在等待鎖的京城會(huì)受到AbandonedMuteException異常。
linux實(shí)現(xiàn)方式是通過(guò)臨時(shí)文件的方式實(shí)現(xiàn)
實(shí)現(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(); } } }
以上代碼只需要復(fù)制一份,在多個(gè)程序中啟動(dòng),調(diào)用MutexDemo.IncrementCounters()則可以看到效果
到此這篇關(guān)于一文帶你了解.Net基于Threading.Mutex實(shí)現(xiàn)互斥鎖的文章就介紹到這了,更多相關(guān).Net 互斥鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
ASP.NET Core中Grpc通信的簡(jiǎn)單用法
這篇文章介紹了ASP.NET Core中Grpc通信的簡(jiǎn)單用法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07.net簡(jiǎn)單使用Log4net的方法(多個(gè)日志配置文件)
log4net是.net中常用的一個(gè)日志記錄工具,下面這篇文章主要給大家介紹了關(guān)于.net簡(jiǎn)單使用Log4net的方法(多個(gè)日志配置文件),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧2018-11-11Excel、記事本數(shù)據(jù)導(dǎo)入到數(shù)據(jù)庫(kù)的實(shí)現(xiàn)方法
將手機(jī)號(hào)批量導(dǎo)入數(shù)據(jù)庫(kù)。思路:先將要導(dǎo)入的文件傳上項(xiàng)目里,然后讀取文件的每行數(shù)據(jù)并插入數(shù)據(jù)庫(kù),操作完后再將上傳的文件刪除2013-10-10asp.net使用Repeater控件中的全選進(jìn)行批量操作實(shí)例
這篇文章主要介紹了asp.net使用Repeater控件中的全選進(jìn)行批量操作方法,實(shí)例分析了Repeater控件的使用技巧,需要的朋友可以參考下2015-01-01ASP.NET列出數(shù)據(jù)庫(kù)活躍鏈接的方法
這篇文章主要介紹了ASP.NET列出數(shù)據(jù)庫(kù)活躍鏈接的方法,實(shí)例分析了asp.net列出數(shù)據(jù)庫(kù)活躍鏈接的原理與實(shí)現(xiàn)技巧,需要的朋友可以參考下2015-06-06ASP.Net防止刷新自動(dòng)觸發(fā)事件的解決方案
ASP.Net防止刷新自動(dòng)觸發(fā)事件的解決方案...2006-09-09詳解ASP.NET Core 之 Identity 入門(mén)(三)
本篇文章主要介紹了ASP.NET Core 之 Identity 入門(mén),主要負(fù)責(zé)對(duì)用戶的身份進(jìn)行認(rèn)證,有興趣的可以了解一下。2016-12-12