亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C#多線程編程中的鎖系統(tǒng)(三)

 更新時(shí)間:2015年04月10日 09:42:11   投稿:junjie  
這篇文章主要介紹了C#多線程編程中的鎖系統(tǒng)(三),本本文主要說(shuō)下基于內(nèi)核模式構(gòu)造的線程同步方式、事件、信號(hào)量以及WaitHandle、AutoResetEvent、ManualResetEvent等內(nèi)容,需要的朋友可以參考下

本章主要說(shuō)下基于內(nèi)核模式構(gòu)造的線程同步方式,事件,信號(hào)量。

目錄

一:理論
二:WaitHandle
三:AutoResetEvent
四:ManualResetEvent
五:總結(jié)

一:理論

我們曉得線程同步可分為,用戶模式構(gòu)造和內(nèi)核模式構(gòu)造。

內(nèi)核模式構(gòu)造:是由windows系統(tǒng)本身使用,內(nèi)核對(duì)象進(jìn)行調(diào)度協(xié)助的。內(nèi)核對(duì)象是系統(tǒng)地址空間中的一個(gè)內(nèi)存塊,由系統(tǒng)創(chuàng)建維護(hù)。

  內(nèi)核對(duì)象為內(nèi)核所擁有,而不為進(jìn)程所擁有,所以不同進(jìn)程可以訪問(wèn)同一個(gè)內(nèi)核對(duì)象, 如進(jìn)程,線程,作業(yè),事件,文件,信號(hào)量,互斥量等都是內(nèi)核對(duì)象。

  而信號(hào)量,互斥體,事件是windows專門用來(lái)幫助我們進(jìn)行線程同步的內(nèi)核對(duì)象。

  對(duì)于線程同步操作來(lái)說(shuō),內(nèi)核對(duì)象只有2個(gè)狀態(tài), 觸發(fā)(終止,true)、未觸發(fā)(非終止,false)。 未觸發(fā)不可調(diào)度,觸發(fā)可調(diào)度。

用戶模式構(gòu)造:是由特殊CPU指令來(lái)協(xié)調(diào)線程,上節(jié)講的volatile實(shí)現(xiàn)就是一種,Interlocked也是。  也可稱為非阻塞線程同步。

二:WaitHandle

在windows編程中,我們通過(guò)API創(chuàng)建一個(gè)內(nèi)核對(duì)象后會(huì)返回一個(gè)句柄,句柄則是每個(gè)進(jìn)程句柄表的索引,而后可以拿到內(nèi)核對(duì)象的指針、掩碼、標(biāo)示等。

 而WaitHandle抽象基類類作用是包裝了一個(gè)windows內(nèi)核對(duì)象的句柄。我們來(lái)看下其中一個(gè)WaitOne的函數(shù)源碼(略精簡(jiǎn))。

 

復(fù)制代碼 代碼如下:

 public virtual bool WaitOne(TimeSpan timeout)
        {
            return WaitOne(timeout, false);
        }

        [System.Security.SecuritySafeCritical]  // auto-generated
        [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "Reviewed for thread-safety.")]
        private bool WaitOne(long timeout, bool exitContext)
        {
            return InternalWaitOne(safeWaitHandle, timeout, hasThreadAffinity, exitContext);
        }
        [System.Security.SecurityCritical] 
        internal static bool InternalWaitOne(SafeHandle waitableSafeHandle, long millisecondsTimeout, bool hasThreadAffinity, bool exitContext)
        {
            Contract.EndContractBlock();
            int ret = WaitOneNative(waitableSafeHandle, (uint)millisecondsTimeout, hasThreadAffinity, exitContext);
           
            if (ret == WAIT_ABANDONED)
            {
                ThrowAbandonedMutexException();
            }
            return (ret != WaitTimeout);
        }
        //調(diào)用win32 waitforsingleobjectEx
        [System.Security.SecurityCritical]
        [ResourceExposure(ResourceScope.None)]
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        private static extern int WaitOneNative(SafeHandle waitableSafeHandle, uint millisecondsTimeout, bool hasThreadAffinity, bool exitContext);
 

 WaitAll 和WaitAny 調(diào)用win32中,waitformultipleobjectsEx函數(shù)。

SignalAndWaitOne 調(diào)用win32中,signalandwait函數(shù)。

調(diào)用api帶ex都是設(shè)置超時(shí)的。 如果我們?cè)赾#中不傳,默認(rèn)是-1 表示無(wú)限期等待。

其中SafeWaitHandle字段,包含了一個(gè)win32內(nèi)核對(duì)象句柄。

理解了WaitHandle其他都好辦了,我們來(lái)看下它的派生類型。

復(fù)制代碼 代碼如下:

WaitHandle
  |——EventWaitHandle                  事件構(gòu)造。
    |——AutoResetEvent
    |——ManualResetEvent
  |——Semaphore                         信號(hào)量構(gòu)造。
  |——Mutex                                 互斥體構(gòu)造。

其中Semaphore和mutex第一章已經(jīng)說(shuō)過(guò)了,下面來(lái)看看其他的。

三:AutoResetEvent

   使用示例如下,有簡(jiǎn)單注釋。   關(guān)于描述,盡量貼近系統(tǒng)自身術(shù)語(yǔ)。

復(fù)制代碼 代碼如下:

static void Main(string[] args)
        {
            //AutoResetEvent example
            //AutoResetEvent 通知正在等待的線程已發(fā)生的事件。
            AutoResetEvent waitHandler = new AutoResetEvent(false);//false 即非終止,未觸發(fā)。
            new Thread(() =>
            {
                waitHandler.WaitOne();  //阻塞當(dāng)前線程,等待底層內(nèi)核對(duì)象收到信號(hào)。
                Console.WriteLine("接收到信號(hào),開(kāi)始處理。");

            }).Start();
            new Thread(() =>
            {
                Thread.Sleep(2000);
                Console.WriteLine("發(fā)信號(hào)");
                waitHandler.Set();    //向內(nèi)核對(duì)象發(fā)送信號(hào)。設(shè)置事件對(duì)象為非終止?fàn)顟B(tài)、false,解除阻塞。 

            }).Start();
            //waitHandler.Close(); //釋放句柄資源。
            //waitHandler.Reset();  //手動(dòng)設(shè)置事件為非終止?fàn)顟B(tài)、false,線程阻止。
            Console.ReadLine();
        }

WaitOne 阻塞線程,非自旋。

Set()   發(fā)出一個(gè)信號(hào)后,設(shè)置事件狀態(tài)為false。  這本應(yīng)該是2步的操作,AutoResetEvent.set()函數(shù),給2步一起自動(dòng)做了,很方便。

四:ManualResetEvent

 這個(gè)和上面基本一樣,從字面來(lái)說(shuō)需要手動(dòng)重置狀態(tài),我們來(lái)看例子。
 

復(fù)制代碼 代碼如下:

 ManualResetEvent manualWaitHandler = new ManualResetEvent(false);//false 即非終止,未觸發(fā)。
            new Thread(() =>
            {
                manualWaitHandler.WaitOne();  //阻塞當(dāng)前線程對(duì)象,等待信號(hào)。
                Console.WriteLine("接收到信號(hào),開(kāi)始處理。");

                manualWaitHandler.Reset();  //手動(dòng) 設(shè)置事件對(duì)象狀態(tài)為非終止?fàn)顟B(tài),false。
                manualWaitHandler.WaitOne();  //這里直接阻塞等待無(wú)效,因?yàn)槭录?duì)象還是true,必須手動(dòng)調(diào)reset。
                Console.WriteLine("第二次接收到信號(hào),開(kāi)始處理。");

            }).Start();
            new Thread(() =>
            {
                Thread.Sleep(2000);
                Console.WriteLine("發(fā)信號(hào)");
                manualWaitHandler.Set();    //向事件對(duì)象發(fā)送ok信號(hào)。。

                Thread.Sleep(2000);
                Console.WriteLine("第二次發(fā)信號(hào)");
                manualWaitHandler.Set();
            }).Start();
            Console.ReadLine();
 

這2則區(qū)別很小,其實(shí)是系統(tǒng)Api的區(qū)分,不是net類庫(kù)實(shí)現(xiàn)的。

在Win32Native類中,我可以看到KERNEL32 api 有這么個(gè)參數(shù)isManualReset。

復(fù)制代碼 代碼如下:

 [DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)]
        [ResourceExposure(ResourceScope.Machine)] // Machine or none based on the value of "name"
        internal static extern SafeWaitHandle CreateEvent(SECURITY_ATTRIBUTES lpSecurityAttributes, bool isManualReset, bool initialState, String name);

五:總結(jié)

基于內(nèi)核模式構(gòu)造的同步步驟是:   托管代碼->用戶模式代碼->內(nèi)核模式代碼。

用戶模式構(gòu)造, 是利用CPU特殊指令,進(jìn)行原子操作。

用戶模式代碼,如圖。 是指  托管代碼調(diào)用 win32代碼 這一層,   之后在調(diào)內(nèi)核模式代碼。

相關(guān)文章

  • .NET實(shí)現(xiàn):將EXE設(shè)置開(kāi)機(jī)自動(dòng)啟動(dòng)

    .NET實(shí)現(xiàn):將EXE設(shè)置開(kāi)機(jī)自動(dòng)啟動(dòng)

    .NET實(shí)現(xiàn):將EXE設(shè)置開(kāi)機(jī)自動(dòng)啟動(dòng)的方法,需要的朋友可以參考一下
    2013-03-03
  • C# 進(jìn)行圖片壓縮的示例代碼(對(duì)jpg壓縮效果最好)

    C# 進(jìn)行圖片壓縮的示例代碼(對(duì)jpg壓縮效果最好)

    這篇文章主要介紹了C# 進(jìn)行圖片壓縮的示例代碼,幫助大家更好的利用c# 處理圖片,提高辦公效率,感興趣的朋友可以了解下
    2020-11-11
  • Unity實(shí)現(xiàn)虛擬鍵盤

    Unity實(shí)現(xiàn)虛擬鍵盤

    這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)虛擬鍵盤,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • C#使用迭代器實(shí)現(xiàn)文字動(dòng)態(tài)效果的示例代碼

    C#使用迭代器實(shí)現(xiàn)文字動(dòng)態(tài)效果的示例代碼

    這篇文章主要為大家詳細(xì)介紹了C#如何通過(guò)使用迭代器實(shí)現(xiàn)文字動(dòng)態(tài)效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-02-02
  • C#中的并發(fā)集合Concurrent類

    C#中的并發(fā)集合Concurrent類

    這篇文章介紹了C#中的并發(fā)集合Concurrent類,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • 描述C#多線程中l(wèi)ock關(guān)鍵字的使用分析

    描述C#多線程中l(wèi)ock關(guān)鍵字的使用分析

    本篇文章是對(duì)C#多線程中l(wèi)ock關(guān)鍵字的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • C#利用GDI+畫圖的基礎(chǔ)實(shí)例教程

    C#利用GDI+畫圖的基礎(chǔ)實(shí)例教程

    編寫圖形程序時(shí)需要使用GDI(Graphics Device Interface,圖形設(shè)備接口),所以通過(guò)網(wǎng)上的相關(guān)資料整理了這篇文章,下面這篇文章主要給大家介紹了關(guān)于C#利用GDI+畫圖基礎(chǔ)的相關(guān)資料,需要的朋友可以參考下。
    2018-04-04
  • 如何通過(guò)IL了解C#類的構(gòu)造函數(shù)淺析

    如何通過(guò)IL了解C#類的構(gòu)造函數(shù)淺析

    這篇文章主要給大家介紹了關(guān)于如何通過(guò)IL了解C#類的構(gòu)造函數(shù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • C#飛機(jī)打字游戲的代碼示例(winform版)

    C#飛機(jī)打字游戲的代碼示例(winform版)

    這篇文章主要介紹了C#飛機(jī)打字游戲的代碼示例(winform版),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • C#中的正則表達(dá)式介紹

    C#中的正則表達(dá)式介紹

    關(guān)于正則表達(dá)式,我們都知道挺繁瑣的。本文介紹的是C#中的正則表達(dá)式,希望對(duì)你有幫助,一起來(lái)看。
    2015-10-10

最新評(píng)論