最新国产好看的视频,伊人天堂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)核對象進行調(diào)度協(xié)助的。內(nèi)核對象是系統(tǒng)地址空間中的一個內(nèi)存塊,由系統(tǒng)創(chuàng)建維護。

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

  而信號量,互斥體,事件是windows專門用來幫助我們進行線程同步的內(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實現(xiàn)就是一種,Interlocked也是。  也可稱為非阻塞線程同步。

二:WaitHandle

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

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

 

復制代碼 代碼如下:

 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#中不傳,默認是-1 表示無限期等待。

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

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

復制代碼 代碼如下:

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

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

三:AutoResetEvent

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

復制代碼 代碼如下:

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

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

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

WaitOne 阻塞線程,非自旋。

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

四:ManualResetEvent

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

復制代碼 代碼如下:

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

                manualWaitHandler.Reset();  //手動 設(shè)置事件對象狀態(tài)為非終止狀態(tài),false。
                manualWaitHandler.WaitOne();  //這里直接阻塞等待無效,因為事件對象還是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ū)別很小,其實是系統(tǒng)Api的區(qū)分,不是net類庫實現(xiàn)的。

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

復制代碼 代碼如下:

 [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特殊指令,進行原子操作。

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

    C#字符串加密解密方法實例

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

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

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

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

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

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

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

    C#?Chart控件標記問題詳解

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

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

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

最新評論

巨鹿县| 中西区| 社旗县| 定州市| 龙海市| 象州县| 盐山县| 颍上县| 青阳县| 昌乐县| 鄱阳县| 龙海市| 翼城县| 张北县| 阜康市| 安康市| 门头沟区| 饶河县| 浙江省| 庄河市| 明星| 白朗县| 麻城市| 正阳县| 罗平县| 左贡县| 资中县| 白山市| 堆龙德庆县| 峨眉山市| 资阳市| 婺源县| 阿克苏市| 泾源县| 上高县| 南宫市| 固始县| 碌曲县| 阜阳市| 周至县| 乌兰浩特市|