欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#之線程同步Mutex類方式

 更新時間:2025年04月11日 09:12:29   作者:haixin-561  
這篇文章主要介紹了C#之線程同步Mutex類方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

Mutex(互斥鎖)

Mutex: 命名空間:System.Threading

一個同步基元,也可用于進程間同步。是.NET Framework 中提供跨多個線程,或多個進程同步訪問的一個類。它非常類似于Monitor類,他們都只有一個線程能擁有鎖定,只有一個線程能獲得互斥鎖,訪問受互斥保護的同步代碼區(qū)域。

在 Mutex 類的構(gòu)造函數(shù)中,可以指定互斥是否最初應(yīng)有主線程擁有,定義互斥的名稱,獲得互斥是否以存在的信息。

例:

  bool flag;
  Mutex mutex = new Mutex(false, "ProcSharpMutex", out flag);

第三個參數(shù)定義輸出參數(shù),接受一個互斥是否為新建的 bool 值。如果返回 False 表示互斥已經(jīng)定義。互斥可以在另一個進程中定義,因為操作系統(tǒng)能夠識別有名子的互斥,它有不同的進程共享。

如果沒有給互斥指定名稱,互斥就是未命名的,不在不同的進程之間共享。

要打開已有的互斥,還可以使用 Mutex.OpenExisting()方法,它不需要用構(gòu)造函數(shù)創(chuàng)建互斥時需要的相同 .NET權(quán)限。

由于 Mutex 派生于 WaitHandle , 因此可以利用 WaitOne() 方法獲得互斥鎖定,在該過程中成為該互斥擁有者。調(diào)用 ReleaseMutex() 方法 ,即可釋放互斥。

例:

			if (mutex.WaitOne())
            {
                try
                {
                    //同步的區(qū)域
                }
                finally
                {
                    mutex.ReleaseMutex();//釋放 mutex 一次
                }
            }
            else
            {
                //等待時發(fā)生了一些問題
            }

構(gòu)造函數(shù)

構(gòu)造函數(shù)描述
Mutex()使用默認屬性初始化 Mutex 類的新實例。
Mutex(Boolean)用一個指示調(diào)用線程是否應(yīng)擁有互斥體的初始所屬權(quán)的布爾值來初始化 Mutex 類的新實例。
Mutex(Boolean, String)用一個指示調(diào)用線程是否應(yīng)擁有互斥體的初始所屬權(quán)的布爾值和一個作為互斥體名稱的字符串來初始化 Mutex 類的新實例。
Mutex(Boolean, String, Boolean)使用可指示調(diào)用線程是否應(yīng)具有互斥體的初始所有權(quán)以及字符串是否為互斥體的名稱的 Boolean 值和當線程返回時可指示調(diào)用線程是否已賦予互斥體的初始所有權(quán)的 Boolean 值初始化 Mutex 類的新實例。
Mutex(Boolean, String, Boolean, MutexSecurity)使用可指示調(diào)用線程是否應(yīng)具有互斥體的初始所有權(quán)以及字符串是否為互斥體的名稱的 Boolean 值和當線程返回時可指示調(diào)用線程是否已賦予互斥體的初始所有權(quán)以及訪問控制安全是否已應(yīng)用到命名互斥體的 Boolean 變量初始化 Mutex 類的新實例。

方法

方法名稱描述
Close()釋放由當前 WaitHandle 占用的所有資源。 (Inherited from WaitHandle)
CreateObjRef(Type)創(chuàng)建一個對象,該對象包含生成用于與遠程對象進行通信的代理所需的全部相關(guān)信息。 (Inherited from MarshalByRefObject)
Dispose()釋放 WaitHandle 類的當前實例所使用的所有資源。 (Inherited from WaitHandle)
Dispose(Boolean)當在派生類中重寫時,釋放 WaitHandle 使用的非托管資源,并且可選擇釋放托管資源。 (Inherited from WaitHandle)
Equals(Object)確定指定的對象是否等于當前對象。 (Inherited from Object)
GetAccessControl()獲取一個 MutexSecurity 對象,該對象表示已命名互斥體的訪問控制安全性。
OpenExisting(String)打開指定名稱為 mutex(如果已經(jīng)存在)。
OpenExisting(String, MutexRights)用安全訪問權(quán)限打開指定名稱為 mutex(如果已經(jīng)存在),并返回指示操作是否成功的值。
ReleaseMutex()釋放 Mutex 一次。
WaitOne()阻止當前線程,直到當前 WaitHandle 收到信號。
WaitOne(Int32)阻止當前線程,直到當前 WaitHandle 收到信號,同時使用 32 位帶符號整數(shù)指定時間間隔(以毫秒為單位)。

屬性

屬性描述
Handle獲取或設(shè)置本機操作系統(tǒng)句柄。
SafeWaitHandle獲取或設(shè)置本機操作系統(tǒng)句柄。

字段

字段描述
WaitTimeout指示在任何等待句柄終止之前 WaitAny(WaitHandle[], Int32, Boolean) 操作已超時。 此字段為常數(shù)。

詳細結(jié)構(gòu)請點擊MSDN 文檔連接: Mutex

基本用法Dome1:

      // 創(chuàng)建一個新的互斥對象。創(chuàng)建線程不擁有互斥對象。
        private static Mutex mut = new Mutex();
        private const int numIterations = 1;
        private const int numThreads = 3;
        static void Main(string[] args)
        {
            // 創(chuàng)建將使用受保護資源的3個線程。
            for (int i = 0; i < numThreads; i++)
            {
                Thread newThread = new Thread(new ThreadStart(ThreadProc));
                newThread.Name = String.Format("Thread{0}", i + 1);
                newThread.Start();
            }

            //主線程退出,但是應(yīng)用程序繼續(xù)運行,直到所有前臺線程退出為止。
            Console.ReadKey();
        }

        private static void ThreadProc()
        {
            for (int i = 0; i < numIterations; i++)
            {
                UseResource();
            }
        }

        //此方法表示必須同步的資源
        //這樣每次只能進入一個線程。
        private static void UseResource()
        {
            // 等安全了再進去。
            Console.WriteLine("{0} 正在請求互斥鎖", Thread.CurrentThread.Name);
            mut.WaitOne();

            Console.WriteLine("{0} 已進入保護區(qū)", Thread.CurrentThread.Name);

            //在這里放置訪問不可重入資源的代碼。

            // 模擬一些工作。
            Thread.Sleep(500);

            Console.WriteLine("{0} 離開保護區(qū)", Thread.CurrentThread.Name);

            // 釋放互斥鎖。
            mut.ReleaseMutex();
            Console.WriteLine("{0} 正在釋放互斥鎖", Thread.CurrentThread.Name);
        }

輸出:每次執(zhí)行進入的先后順序都不一樣

Dome2: 每個線程調(diào)用WaitOne(Int32)方法以獲取互斥體。 如果達到超時間隔,該方法返回false,并在線程獲取 mutex 既不獲得互斥鎖保護的資源訪問權(quán)。 ReleaseMutex只能由獲得該互斥體的線程調(diào)用方法。

        // 創(chuàng)建一個新的互斥對象。創(chuàng)建線程不擁有互斥對象。
        private static Mutex mut = new Mutex();
        private const int numIterations = 1;
        private const int numThreads = 3;
        static void Main(string[] args)
        {
            Program p = new Program();
            p.StartThreads();

            Console.ReadKey();//這里阻塞一下,可以看到輸出結(jié)果
        }

        private void StartThreads()
        {
            // 創(chuàng)建將使用受保護資源的3個線程。
            for (int i = 0; i < numThreads; i++)
            {
                Thread newThread = new Thread(new ThreadStart(ThreadProc));
                newThread.Name = String.Format("Thread{0}", i + 1);
                newThread.Start();
            }

            //主線程退出,但是應(yīng)用程序繼續(xù)運行,直到所有前臺線程退出為止。
           
        }
        private static void ThreadProc()
        {
            for (int i = 0; i < numIterations; i++)
            {
                UseResource();
            }
        }

        //此方法表示必須同步的資源
        //這樣每次只能進入一個線程。
        private static void UseResource()
        {
            // 等安全了再進去。
            Console.WriteLine("{0} 正在請求互斥鎖", Thread.CurrentThread.Name);
            if(mut.WaitOne(1000))
            {
                Console.WriteLine("{0} 已進入保護區(qū)", Thread.CurrentThread.Name);

                //在這里放置訪問不可重入資源的代碼。

                // 模擬一些工作。
                Thread.Sleep(500);

                Console.WriteLine("{0} 離開保護區(qū)", Thread.CurrentThread.Name);

                // 釋放互斥鎖。
                mut.ReleaseMutex();
                Console.WriteLine("{0} 正在釋放互斥鎖", Thread.CurrentThread.Name);
            }
            else
            {
                Console.WriteLine("{0} 沒有獲取互斥鎖",   Thread.CurrentThread.Name);
            }
        }
        ~Program()
        {
            mut.Dispose();
        }

輸出結(jié)果:

重要

此類型實現(xiàn)IDisposable接口。 在使用完類型后,您應(yīng)直接或間接釋放類型。 若要直接釋放類型,調(diào)用其Dispose中的方法 try / catch塊。 若要間接釋放類型,請使用 using(在 C# 中)或 Using

可以使用WaitHandle.WaitOne來請求所有權(quán)的互斥體的方法。 調(diào)用線程受到阻止,直到發(fā)生下列情況之一:

  1. 互斥體是發(fā)出信號,以指示它不屬于。 在此情況下,WaitOne方法將返回true,調(diào)用線程是互斥體的所有權(quán),并訪問受該互斥體的資源。 完成后訪問資源,必須調(diào)用線程ReleaseMutex方法來釋放 mutex 的所有權(quán)。 示例部分中的第一個示例說明了此模式。
  2. 對的調(diào)用中指定的超時間隔WaitOne具有方法millisecondsTimeout或timeout參數(shù)已過。 在此情況下,WaitOne方法將返回false,并調(diào)用線程不會進一步嘗試獲取 mutex 的所有權(quán)。 在這種情況下,您應(yīng)構(gòu)建你的代碼,以便由 mutex 保護資源的訪問權(quán)限被拒絕對調(diào)用線程。 線程永遠不會獲取 mutex 的所有權(quán),因為它不能調(diào)用ReleaseMutex方法。 示例部分中的第二個示例說明了此模式。

Mutex類強制線程標識,因此只能由獲得它的線程可以釋放互斥體。 與此相反,Semaphore類不會強制線程標識。 此外可以跨應(yīng)用程序域邊界傳遞了互斥體。

擁有 mutex 的線程可以請求中重復調(diào)用相同的互斥體WaitOne而不會阻止其執(zhí)行。 但是,調(diào)用線程必須ReleaseMutex方法相同數(shù)量的次數(shù)與釋放 mutex 的所有權(quán)。

因為Mutex類繼承自WaitHandle,你還可以調(diào)用靜態(tài)WaitHandle.WaitAll和WaitHandle.WaitAny方法來同步受保護資源的訪問權(quán)限。

如果線程終止時擁有互斥體,則認為該 mutex 已放棄。 互斥體的狀態(tài)設(shè)置為終止狀態(tài),并且下一個等待線程獲取所有權(quán)。 從.NET Framework 的版本 2.0AbandonedMutexException獲取已放棄的互斥體的下一個線程中引發(fā)。 在.NET Framework 2.0 版中之前, 未不引發(fā)任何異常。

注意

放棄的 mutex 通常表明代碼中的存在嚴重錯誤。 線程退出時不釋放互斥體,由 mutex 保護的數(shù)據(jù)結(jié)構(gòu)不可能處于一致狀態(tài)。 為請求 mutex 所有權(quán)的下一個線程可以處理此異常并繼續(xù)操作,如果可以驗證數(shù)據(jù)結(jié)構(gòu)的完整性。

對于系統(tǒng)范圍的 mutex,放棄的 mutex 可能指示應(yīng)用程序已突然終止(例如,通過使用 Windows 任務(wù)管理器終止)。

Mutex 有兩種類型: 本地 mutex,未命名,并命名系統(tǒng) mutex。 本地 mutex 僅存在于進程中。 可由您具有對引用的過程中的任何線程Mutex表示該互斥體的對象。 每個未命名Mutex對象表示單獨的本地 mutex。

已命名的系統(tǒng)互斥體,顯示整個操作系統(tǒng),可用于同步進程的活動。 您可以創(chuàng)建Mutex使用接受名稱的構(gòu)造函數(shù)表示命名的系統(tǒng)互斥體對象。 可以在同一時間創(chuàng)建操作系統(tǒng)對象也可以在創(chuàng)建之前存在Mutex對象。 可以創(chuàng)建多個表示同一命名系統(tǒng) mutex 的 Mutex 對象,還能使用 OpenExisting 方法打開現(xiàn)有的命名系統(tǒng) mutex。

備注:

在運行終端服務(wù)的服務(wù)器,命名的系統(tǒng)互斥體可以包含兩個級別的可見性。 如果其名稱以前綴開頭"Global",互斥體是在所有終端服務(wù)器會話中可見。 如果其名稱以前綴開頭"本地",互斥體是僅在終端服務(wù)器會話中可見的創(chuàng)建位置。 在這種情況下,具有相同名稱單獨的互斥鎖可以存在于每個服務(wù)器上的其他終端服務(wù)器會話。 如果您不指定前綴創(chuàng)建已命名的互斥體時,它將前綴"本地"。 終端服務(wù)器會話中,只能由其前綴的名稱不同的兩個 mutex 有單獨的互斥體,且都在終端服務(wù)器會話中對所有進程可見。 也就是說,前綴名稱"Global"和"本地"描述相對于終端服務(wù)器會話、 不相對于進程的互斥體名稱的作用域。

反斜杠 () 是互斥體名稱中的保留字符。 請勿在互斥體名稱中使用反斜杠 (),除非在終端服務(wù)器會話中使用互斥體的注釋中另有規(guī)定。 否則,即使互斥體的名稱表示現(xiàn)有文件,也可能引發(fā) DirectoryNotFoundException。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • C# BinaryReader實現(xiàn)讀取二進制文件

    C# BinaryReader實現(xiàn)讀取二進制文件

    在 C# 以二進制形式讀取數(shù)據(jù)時使用的是 BinaryReader 類。本文介紹了C# BinaryReader實現(xiàn)讀取二進制文件,感興趣的可以了解一下
    2021-06-06
  • Unity ScrollRect實現(xiàn)軌跡滑動效果

    Unity ScrollRect實現(xiàn)軌跡滑動效果

    這篇文章主要為大家詳細介紹了Unity ScrollRect實現(xiàn)軌跡滑動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • C#將List轉(zhuǎn)換為只讀的List方法與技巧

    C#將List轉(zhuǎn)換為只讀的List方法與技巧

    在 C# 編程的廣闊世界里,數(shù)據(jù)的安全性與穩(wěn)定性始終是我們關(guān)注的焦點,當涉及到集合數(shù)據(jù)的處理時,有時我們會面臨這樣一個關(guān)鍵需求:將List轉(zhuǎn)換為只讀的List,所以本文給大家介紹了使用C#將List轉(zhuǎn)換為只讀的List的方法與技巧,需要的朋友可以參考下
    2025-01-01
  • C#使用Task.ContinueWith組合任務(wù)

    C#使用Task.ContinueWith組合任務(wù)

    這篇文章介紹了C#使用Task.ContinueWith組合任務(wù)的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • 基于Unity3D實現(xiàn)仿真時鐘詳解

    基于Unity3D實現(xiàn)仿真時鐘詳解

    這篇文章主要為大家詳細介紹了如何利用Unity3D模擬實現(xiàn)一個簡單是時鐘效果,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-01-01
  • C#中GraphicsPath的AddString方法用法實例

    C#中GraphicsPath的AddString方法用法實例

    這篇文章主要介紹了C#中GraphicsPath的AddString方法用法,實例分析了AddString方法添加字符串的相關(guān)使用技巧,需要的朋友可以參考下
    2015-06-06
  • C#批量插入數(shù)據(jù)到Sqlserver中的三種方式

    C#批量插入數(shù)據(jù)到Sqlserver中的三種方式

    這篇文章主要為大家詳細介紹了C#批量插入數(shù)據(jù)到Sqlserver中的三種方式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • 深入委托與多播委托的詳解

    深入委托與多播委托的詳解

    本篇文章是對委托與多播委托進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06
  • C#中Override關(guān)鍵字和New關(guān)鍵字的用法詳解

    C#中Override關(guān)鍵字和New關(guān)鍵字的用法詳解

    這篇文章主要介紹了C#中Override關(guān)鍵字和New關(guān)鍵字的用法,需要的朋友可以參考下
    2016-01-01
  • WCF基礎(chǔ)介紹并創(chuàng)建簡單應(yīng)用程序

    WCF基礎(chǔ)介紹并創(chuàng)建簡單應(yīng)用程序

    這篇文章介紹了WCF基礎(chǔ)并創(chuàng)建簡單WCF應(yīng)用程序,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-01-01

最新評論