1. 程式人生 > 程式設計 >一文帶你瞭解.Net基於Threading.Mutex實現互斥鎖

一文帶你瞭解.Net基於Threading.Mutex實現互斥鎖

本文主要講解.Net基於Threading.Mutex實現互斥鎖

基礎互斥鎖實現

基礎概念:和自旋鎖一樣,作業系統提供的互斥鎖內部有一個數值表示鎖是否已經被獲取,不同的是當獲取鎖失敗的時候,它不會反覆進行重試,而且讓執行緒進入等待狀態,並把執行緒物件新增到鎖關聯的佇列中,另一個執行緒釋放鎖時會檢查佇列中是否有執行緒物件,如果有則通知作業系統喚醒該執行緒,因為獲取鎖的執行緒物件沒有進行執行,即使鎖長時間不釋放也不會消耗CPU資源,但讓執行緒進入等待狀態和從等待狀態喚醒的時間比自旋鎖重試的納秒級時間要長

windows和linux的區別

在windows系統上http://www.cppcns.com

互斥鎖通過CreateMuteEx函式建立,獲取鎖時將呼叫WaitForMultipleObjectsEx函式,釋放鎖將呼叫ReleaseMutex函式,執行緒進入等待狀態和喚醒由系統操作
在Linux上互斥鎖物件由NetCore的內部介面模擬實現,結果包含鎖的狀態值以及等待執行緒佇列,每個託管執行緒都會關聯一個pthread_mutex_t物件和一個pthread_cond_t物件,這兩個物件友pthread類庫提供,獲取鎖失敗執行緒會調價到佇列pthread_cond_wait函式等待,另一個執行緒釋放鎖時看到佇列中有執行緒則呼叫pthread_cond_signal函式喚醒。

基礎互斥鎖程式碼實現

 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();
            }
        }


    }

互斥鎖(遞迴鎖)

基礎概念:Mutex提供的鎖可重入,已經獲取鎖的執行緒可以再次執行獲取鎖的操作,但釋放鎖的操作也要執行對應的相同次數,可重入的鎖又叫遞迴鎖。

實現原理:遞迴鎖內部使用一個計數器記錄進入次數,同一個執行緒每獲取一次就加1,釋放一次就減1,減1後如果計算器為0就執行真正的釋放操作。遞迴鎖在單個函式中使用沒有意義,一般巢狀在多個函式中

程式碼實現

public static class MutexRecursionDemo
    {
        private static Mutex _lock = new Mutexhttp://www.cppcns.com(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();
            }
        }
    }

互斥鎖(跨程序使用)

基礎概念:Mutex支援誇程序使用,建立是通過建構函式的第二個引數name傳入名稱,名稱以Walterlv.Mutex開始時同一個使用者的程序共享擁有此名稱的鎖,如果一個程序中獲取了鎖,那麼在釋放該鎖前另一個程序獲取同樣名稱的鎖需要等待,如果程序獲取了鎖,但是在退出之前沒有呼叫釋放鎖的方法,那麼鎖會被自動釋放,其他當前正在等待鎖的京城會受到AbandonedMuteException異常。

linux實現方式是通過臨時檔案的方式實現

實現程式碼

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()
        {
        uxbbnmmw    //獲取鎖
            _lock.WaitOne();
            try
            {
                ++_counterA;
                ++_counterB;
            }
            finally
            {
                //釋放鎖
                _lock.ReleaseMutex();
            }
        }

        public static void GetCounters(out int counterA程式設計客棧,out int counterB)
       uxbbnmmw {
            _lock.WaitOne();
            try
            {
                counterA = _counterA;
                counterB = _counterB;
            }
            finally
            {
                //釋放鎖
                _lock.ReleaseMutex();
            }
        }
    }

以上程式碼只需要複製一份,在多個程式中啟動,呼叫MutexDemo.IncrementCounters()則可以看到效果

到此這篇關於一文帶你瞭解.Net基於Threading.Mutex實現互斥鎖的文章就介紹到這了,更多相關.Net 互斥鎖內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!