亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

細說.NET中的多線程(六使用MemoryBarrier,Volatile進行同步)

2019-11-14 13:49:22
字體:
來源:轉載
供稿:網友

上一節介紹了使用信號量進行同步,本節主要介紹一些非阻塞同步的方法。本節主要介紹MemoryBarrier,volatile,Interlocked。

MemoryBarriers

本文簡單的介紹一下這兩個概念,假設下面的代碼:

using System;class Foo{    int _answer;    bool _complete;    void A()    {        _answer = 123;        _complete = true;    }    void B()    {        if (_complete) Console.WriteLine(_answer);    }}

如果方法A和方法B同時在兩個不同線程中運行,控制臺可能輸出0嗎?答案是可能的,有以下兩個原因:

  • 編譯器,CLR或者CPU可能會更改指令的順序來提高性能
  • 編譯器,CLR或者CPU可能會通過緩存來優化變量,這種情況下對其他線程是不可見的。

最簡單的方式就是通過MemoryBarrier來保護變量,來防止任何形式的更改指令順序或者緩存。調用Thread.MemoryBarrier會生成一個內存柵欄,我們可以通過以下的方式解決上面的問題:

using System;using System.Threading;class Foo{    int _answer;    bool _complete;    void A()    {        _answer = 123;        Thread.MemoryBarrier();    // Barrier 1        _complete = true;        Thread.MemoryBarrier();    // Barrier 2    }    void B()    {        Thread.MemoryBarrier();    // Barrier 3        if (_complete)        {            Thread.MemoryBarrier();       // Barrier 4            Console.WriteLine(_answer);        }    }}

上面的例子中,barrier1和barrier3用來保證指令順序不會改變,barrier2和barrier4用來保證值變化不被緩存。一個好的處理方案就是我們在需要保護的變量前后分別加上MemoryBarrier。

在c#中,下面的操作都會生成MemoryBarrier:

  • Lock語句(Monitor.Enter,Monitor.Exit)
  • 所有Interlocked類的方法
  • 線程池的回調方法
  • Set或者Wait信號
  • 所有依賴于信號燈實現的方法,如starting或waiting 一個Task

因為上面這些行為,這段代碼實際上是線程安全的:

        int x = 0;        Task t = Task.Factory.StartNew(() => x++);        t.Wait();        Console.WriteLine(x);    // 1

在你自己的程序中,你可能重現不出來上面例子所說的情況。事實上,從msdn上對MomoryBarrier的解釋來看,只有對順序保護比較弱的多核系統才需要用到MomoryBarrier。但是有一點需要注意:多線程去修改變量并且不使用任何形似的鎖或者內存柵欄是會帶來一定的麻煩的。

下面一個例子能夠很好的說明上面的觀點(在你的VisualStudio中,選擇Release模式,并且Start Without Debugging重現這個問題):

        bool complete = false;        var t = new Thread(() =>        {            bool toggle = false;            while (!complete) toggle = !toggle;        });        t.Start();        Thread.Sleep(1000);        complete = true;        t.Join();        // Blocks indefinitely

這個程序永遠不會結束,因為complete變量被緩存在了CPU寄存器中。在while循環中加入Thread.MemoryBarrier可以解決這個問題。

volatile關鍵字

另外一種更高級的方式來解決上面的問題,那就是考慮使用volatile關鍵字。Volatile關鍵字告訴編譯器在每一次讀操作時生成一個fence,來實現保護保護變量的目的。具體說明可以參見msdn的介紹

VolatileRead和VolatileWrite

Volatile關鍵字只能加到類變量中。本地變量不能被聲明成volatile。這種情況你可以考慮使用System.Threading.Volatile.Read方法。我們看一下System.Threading.Volatile源碼如何實現這兩個方法的:

    public static bool Read(ref bool location)    {        bool flag = location;        Thread.MemoryBarrier();        return flag;    }    public static void Write(ref bool location, bool value)    {        Thread.MemoryBarrier();        location = value;    }

  

一目了然,通過MemoryBarrier來實現的,但是他只在讀操作的后面和寫操作的前面加了MemoryBarrier,那么你應該考慮,如果你先使用Volatile.Write再使用Volatile.Read是不是可能有問題呢?

c#中ConcurrentDictionary中使用了Volatile類來保護變量,有興趣的讀者可以看看c#的開發者是如何使用這個方法來保護變量的。

Interlocked

使用MemoryBarrier并不總是一個好的解決方案,尤其在不需要鎖的情況下。Interlocked方法提供了一些常用的原子操作來避免前面文章提到的一系列的問題。如使用Interlocked.Increment來替代++,Interlocked.Decrement來替代--。Msdn的文檔中詳細的介紹了相關的用法和原理。C#中的源碼里也經常能看見Interlocked相關的使用。

 

本文介紹了一些除了鎖和信號量之外的一些同步方式,歡迎批評與指正。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲a区在线视频| 中文字幕日韩在线播放| 精品一区二区三区三区| 91香蕉嫩草神马影院在线观看| 久久精视频免费在线久久完整在线看| 97国产在线观看| 日韩在线播放一区| 国产精品扒开腿爽爽爽视频| 日本国产精品视频| 一区二区亚洲欧洲国产日韩| 日韩欧美一区二区三区| 欧美中文字幕在线| 中文在线资源观看视频网站免费不卡| 国产成人精品午夜| 国产国语刺激对白av不卡| 欧美一级在线播放| 国产精品国产三级国产专播精品人| 亚洲欧美自拍一区| 91久久国产婷婷一区二区| 欧美美最猛性xxxxxx| 久久久久久久久久婷婷| 日本一区二区在线播放| 日韩中文在线中文网三级| 97精品国产97久久久久久春色| 久久99精品久久久久久琪琪| 韩国三级电影久久久久久| 成人中文字幕+乱码+中文字幕| 欧美成人在线免费视频| 91成人天堂久久成人| 国产日韩欧美另类| 4444欧美成人kkkk| 欧美大成色www永久网站婷| 久久久999国产精品| 精品久久久久久中文字幕| 亚洲电影在线看| 亚洲va久久久噜噜噜| 日韩精品中文字幕有码专区| 国产一区二区视频在线观看| 欧美激情免费视频| 亚洲黄色在线观看| 亚洲精品免费在线视频| 成人午夜在线观看| 亚洲热线99精品视频| 国产精品久久久久久久av电影| 精品亚洲va在线va天堂资源站| 久久久精品2019中文字幕神马| 日韩av在线不卡| 久久精视频免费在线久久完整在线看| 成人美女av在线直播| 俺去啦;欧美日韩| 成人黄色短视频在线观看| 日韩中文字幕久久| 亚洲精品小视频| 国产精品久久久久久av| 岛国视频午夜一区免费在线观看| 欧美黄网免费在线观看| 91精品国产91久久久久| 日韩精品亚洲元码| 国产亚洲激情在线| 欧美一区二区三区四区在线| 国产精品96久久久久久| 成人高h视频在线| 欧美精品做受xxx性少妇| 成人h片在线播放免费网站| 在线一区二区日韩| 国产精品久久久久久久久久久久| 国产免费观看久久黄| 欧美日韩高清在线观看| 国产亚洲在线播放| 亚洲成人黄色网| 国语自产精品视频在线看一大j8| 亚洲福利视频久久| 欧美大片在线免费观看| 国产有码在线一区二区视频| 久久久精品在线| 亚洲国产精品久久久| 国产精品视频资源| 啪一啪鲁一鲁2019在线视频| 国产成人精品在线播放| 尤物九九久久国产精品的分类| 国产成人97精品免费看片| 亚洲一区二区三区毛片| 成人av资源在线播放| 欧美日韩国产二区| 九九热精品视频| 亚洲伦理中文字幕| 日韩中文视频免费在线观看| 91九色单男在线观看| 97成人精品区在线播放| 日本视频久久久| 国产女人18毛片水18精品| 成人黄色影片在线| 91人成网站www| 欧美日韩国产一中文字不卡| 成人免费视频97| 97在线看免费观看视频在线观看| 日韩av在线免费看| 中文.日本.精品| 国内久久久精品| 日韩视频一区在线| 国产精欧美一区二区三区| 日韩免费中文字幕| 国产在线拍揄自揄视频不卡99| 黄网动漫久久久| 久久免费少妇高潮久久精品99| 精品久久久久久久久久久久| 日韩一区二区三区在线播放| 亚洲热线99精品视频| 欧美在线视频在线播放完整版免费观看| 亚洲欧美日韩区| 色噜噜国产精品视频一区二区| 亚洲乱码国产乱码精品精| 亚洲国产精品成人va在线观看| 欧美在线亚洲一区| 国产91在线高潮白浆在线观看| 国产91在线视频| 亚洲综合自拍一区| 欧美性高潮在线| 欧美专区第一页| 国产在线播放不卡| 欧美性猛交xxxx久久久| 亚洲欧美中文在线视频| 成人激情视频在线播放| 日韩欧美有码在线| 最近中文字幕2019免费| 色综合视频一区中文字幕| 国产精品视频成人| 亚洲第一av网站| 精品无人国产偷自产在线| 日韩精品免费在线视频| 久久久伊人欧美| 日韩欧美一区二区三区久久| 国产999精品久久久影片官网| 日韩av在线影院| 成人乱人伦精品视频在线观看| 欧美日韩在线另类| 国产精品丝袜久久久久久高清| 欧美日韩国产在线| 在线亚洲午夜片av大片| 国产精品爽黄69| 国产一级揄自揄精品视频| 日本亚洲欧洲色α| 国产亚洲一区二区在线| 日韩成人中文电影| 亚洲一区二区三区视频| 国产成一区二区| 97色在线视频观看| 亚洲欧美在线免费观看| 538国产精品一区二区免费视频| 国产亚洲欧美日韩美女| 国产美女被下药99| 日韩视频免费在线观看| 91精品国产乱码久久久久久蜜臀| 欧洲精品久久久| 26uuu另类亚洲欧美日本一| 岛国视频午夜一区免费在线观看| www.国产一区| 中文字幕日韩在线观看| 综合136福利视频在线| 亚洲男人天堂网| 欧美视频不卡中文| 亚洲欧美日韩精品久久奇米色影视| 欧美床上激情在线观看| 日韩亚洲国产中文字幕|