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

C#之線程同步Mutex類方式

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

Mutex(互斥鎖)

Mutex: 命名空間:System.Threading

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

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

例:

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

第三個(gè)參數(shù)定義輸出參數(shù),接受一個(gè)互斥是否為新建的 bool 值。如果返回 False 表示互斥已經(jīng)定義?;コ饪梢栽诹硪粋€(gè)進(jìn)程中定義,因?yàn)椴僮飨到y(tǒng)能夠識(shí)別有名子的互斥,它有不同的進(jìn)程共享。

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

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

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

例:

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

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

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

方法

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

屬性

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

字段

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

詳細(xì)結(jié)構(gòu)請(qǐng)點(diǎn)擊MSDN 文檔連接: Mutex

基本用法Dome1:

      // 創(chuàng)建一個(gè)新的互斥對(duì)象。創(chuàng)建線程不擁有互斥對(duì)象。
        private static Mutex mut = new Mutex();
        private const int numIterations = 1;
        private const int numThreads = 3;
        static void Main(string[] args)
        {
            // 創(chuàng)建將使用受保護(hù)資源的3個(gè)線程。
            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ù)運(yùn)行,直到所有前臺(tái)線程退出為止。
            Console.ReadKey();
        }

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

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

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

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

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

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

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

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

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

        // 創(chuàng)建一個(gè)新的互斥對(duì)象。創(chuàng)建線程不擁有互斥對(duì)象。
        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)建將使用受保護(hù)資源的3個(gè)線程。
            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ù)運(yùn)行,直到所有前臺(tái)線程退出為止。
           
        }
        private static void ThreadProc()
        {
            for (int i = 0; i < numIterations; i++)
            {
                UseResource();
            }
        }

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

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

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

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

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

輸出結(jié)果:

重要

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

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

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

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

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

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

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

注意

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

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

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

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

備注:

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

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

總結(jié)

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

相關(guān)文章

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

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

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

    Unity ScrollRect實(shí)現(xiàn)軌跡滑動(dòng)效果

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

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

    在 C# 編程的廣闊世界里,數(shù)據(jù)的安全性與穩(wěn)定性始終是我們關(guān)注的焦點(diǎn),當(dāng)涉及到集合數(shù)據(jù)的處理時(shí),有時(shí)我們會(huì)面臨這樣一個(gè)關(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ù)的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • 基于Unity3D實(shí)現(xiàn)仿真時(shí)鐘詳解

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

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

    C#中GraphicsPath的AddString方法用法實(shí)例

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

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

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

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

    本篇文章是對(duì)委托與多播委托進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    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)建簡(jiǎn)單應(yīng)用程序

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

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

最新評(píng)論