最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

目錄

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

一:理論

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

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

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

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

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

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

二:WaitHandle

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

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

 

復(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è)置超時的。 如果我們在c#中不傳,默認(rèn)是-1 表示無限期等待。

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

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

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

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

其中Semaphore和mutex第一章已經(jīng)說過了,下面來看看其他的。

三:AutoResetEvent

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

復(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)核對象收到信號。
                Console.WriteLine("接收到信號,開始處理。");

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

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

WaitOne 阻塞線程,非自旋。

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

四:ManualResetEvent

 這個和上面基本一樣,從字面來說需要手動重置狀態(tài),我們來看例子。
 

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

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

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

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

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

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

在Win32Native類中,我可以看到KERNEL32 api 有這么個參數(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)文章

  • C#創(chuàng)建背景色漸變窗體的方法實(shí)例

    C#創(chuàng)建背景色漸變窗體的方法實(shí)例

    在窗體設(shè)計(jì)時,可以通過設(shè)置窗體的BackColor屬性來改變窗口的背景顏色,但是該屬性改變后整個窗體的客戶區(qū)都會變成這種顏色,這樣顯得非常單調(diào),本文給大家介紹了C#創(chuàng)建背景色漸變窗體的方法實(shí)例,需要的朋友可以參考下
    2024-04-04
  • 深入淺出23種設(shè)計(jì)模式

    深入淺出23種設(shè)計(jì)模式

    本文給大家詳解23種設(shè)計(jì)模式,理解設(shè)計(jì)模式有助于在程序開發(fā)過程中靈活應(yīng)用,需要的朋友可以參考下
    2015-08-08
  • c# 基于wpf,開發(fā)OFD電子文檔閱讀器

    c# 基于wpf,開發(fā)OFD電子文檔閱讀器

    這篇文章主要介紹了c# 如何基于wpf,開發(fā)OFD電子文檔閱讀器,幫助大家更好的理解和學(xué)習(xí)使用c#的wpf技術(shù),感興趣的朋友可以了解下
    2021-03-03
  • C#使用LINQ查詢操作符實(shí)例代碼(二)

    C#使用LINQ查詢操作符實(shí)例代碼(二)

    這篇文章介紹了C#使用LINQ查詢操作符的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • C#字符串加密解密方法實(shí)例

    C#字符串加密解密方法實(shí)例

    這篇文章主要介紹了C#字符串加密解密方法,實(shí)例分析了C#對字符串加密與解密的操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-03-03
  • C#如何正確實(shí)現(xiàn)一個自定義異常Exception

    C#如何正確實(shí)現(xiàn)一個自定義異常Exception

    這篇文章主要為大家詳細(xì)介紹了C#如何正確實(shí)現(xiàn)一個自定義異常Exception,文中的示例代碼簡潔易懂,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-09-09
  • C#播放鈴聲最簡單實(shí)現(xiàn)方法

    C#播放鈴聲最簡單實(shí)現(xiàn)方法

    這篇文章主要介紹了C#播放鈴聲最簡單實(shí)現(xiàn)方法,通過調(diào)用系統(tǒng)方法實(shí)現(xiàn)播放wav格式音頻文件的功能,是非常實(shí)用的技巧,需要的朋友可以參考下
    2014-12-12
  • 淺談Async和Await如何簡化異步編程(幾個實(shí)例讓你徹底明白)

    淺談Async和Await如何簡化異步編程(幾個實(shí)例讓你徹底明白)

    本篇文章主要介紹了淺談Async和Await如何簡化異步編程,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-12-12
  • C#?Chart控件標(biāo)記問題詳解

    C#?Chart控件標(biāo)記問題詳解

    這篇文章主要介紹了C#?Chart控件標(biāo)記問題詳解,在做項(xiàng)目的時候,遇到一個需求,需要我對Chart圖標(biāo)標(biāo)記數(shù)據(jù)正在運(yùn)行,實(shí)現(xiàn)數(shù)據(jù)可視化,文章通過圍繞主題展開詳情,需要的朋友可以參考一下
    2022-08-08
  • C#?漢字與拼音互轉(zhuǎn)的實(shí)現(xiàn)示例

    C#?漢字與拼音互轉(zhuǎn)的實(shí)現(xiàn)示例

    本文主要介紹了C#?漢字與拼音互轉(zhuǎn)的實(shí)現(xiàn)示例,文中根據(jù)實(shí)例編碼詳細(xì)介紹的十分詳盡,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03

最新評論

门头沟区| 荆门市| 酒泉市| 余庆县| 长治县| 金湖县| 宣武区| 都兰县| 陇西县| 武夷山市| 石城县| 车险| 松阳县| 观塘区| 吉首市| 江城| 苗栗市| 榆中县| 江北区| 崇仁县| 苍梧县| 平顺县| 孟州市| 建湖县| 莱州市| 灌云县| 张家口市| 兰溪市| 德州市| 华蓥市| 彭水| 奉新县| 金门县| 宣武区| 绥阳县| 砚山县| 温泉县| 屏边| 佛冈县| 镇巴县| 勐海县|