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

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)文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

最新評論