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

首頁 > 編程 > C# > 正文

C#多線程編程中的鎖系統(二)

2020-01-24 02:00:48
字體:
來源:轉載
供稿:網友

上章主要講排他鎖的直接使用方式。但實際當中全部都用鎖又太浪費了,或者排他鎖粒度太大了。 這一次我們說說升級鎖和原子操作。

目錄
1:volatile
2:  Interlocked
3:ReaderWriterLockSlim
4:總結

一:volatile

簡單來說: volatile關鍵字是告訴c#編譯器和JIT編譯器,不對volatile標記的字段做任何的緩存。確保字段讀寫都是原子操作,最新值。

這不就是鎖嗎?   其這貨它根本不是鎖, 它的原子操作是基于CPU本身的,非阻塞的。 因為32位CPU執行賦值指令,數據傳輸最大寬度4個字節。

所以只要在4個字節以下讀寫操作的,32位CPU都是原子操作。volatile 它就是利用這個特性來的。

好殘酷的事實?不然,微軟大法這樣是為了提高JIT性能效率,對有些數據進行緩存了(多線程下)。

復制代碼 代碼如下:

  //正確
       public volatile Int32 score1 = 1;
        //報錯
        public volatile Int64 score2 = 1;

看上面的例子,我們定義8個字節長度score2就不行了。  因為8個字節,32位CPU就分成2個指令執行了。自然就無法保證原子操作了。

這么細節的,忘了怎么辦,那豈不是坑人啊。  于是微軟大法直接一棍子打死,限制4個字節以下的類型字段才能用volatile,具體什么、看msdn吧。

那今天我知道了。我編譯平臺改成64位上,只在64位CPU用volatile  int64,行不行?  不行,編譯器報錯。說了一棍子打死了。。

(^._.^)ノ  好吧,其實可以用IntPtr這個。

 volatile多數情況下很有用處的,畢竟鎖的性能開銷還是很大的。我們可以把當成輕量級的鎖,根據具體場景合理使用,能提高不少程序性能。

線程中的Thread.VolatileRead 和Thread.VolatileWrite 就是volatile的復雜版。

二:Interlocked

MSDN 描述:為多個線程共享的變量提供原子操作。主要函數如下:

Interlocked.Increment    原子操作,遞增指定變量的值并存儲結果。
Interlocked.Decrement       原子操作,遞減指定變量的值并存儲結果。
Interlocked.Add        原子操作,添加兩個整數并用兩者的和替換第一個整數

Interlocked.CompareExchange(ref a, b, c);  原子操作,a參數和c參數比較,  相等b替換a,不相等不替換。

基本用法就不多說了。直接來段CLR via C# interlock anything的例子:

復制代碼 代碼如下:

public static int Maximum(ref int target, int value)
        {
            int currentVal = target, startVal, desiredVal;  //記錄前后值
            do
            {
                startVal = currentVal; //記錄循環迭代的初始值。
                desiredVal = Math.Max(startVal, value); //基于startVal和value計算期望值desiredVal

                //高并發下,線程被搶占情況下,target值會發生改變。

                //target startVal相等說明沒改變。desiredVal 直接替換。
                currentVal = Interlocked.CompareExchange(ref target, desiredVal, startVal);

            } while (startVal != currentVal); //不相等說明,target值已經被其他線程改動。自旋繼續。
            return desiredVal;
        }

三:ReaderWriterLockSlim

假如我們有份緩存數據A,如果每次都不管任何操作lock一下,那么我的這份緩存A就永遠只能單線程讀寫了, 這在Web高并發下是不能忍受的。

那有沒有一種辦法我只在寫入時進入獨占鎖呢,讀操作時不限制線程數量呢?答案就是我們的ReaderWriterLockSlim主角,讀寫鎖。

ReaderWriterLockSlim 其中一種鎖EnterUpgradeableReadLock最關鍵  即可升級鎖。 

它呢允許你先進入讀鎖,發現緩存A不一樣了, 再進入寫鎖,寫入后退回讀鎖模式。

ps: 這里注意下net 3.5之前有個ReaderWriterLock 性能較差。推薦使用升級版的 ReaderWriterLockSlim 。

復制代碼 代碼如下:

//實例一個讀寫鎖
 ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);

上面實例一個讀寫鎖,這里注意的是構造函數的枚舉。

LockRecursionPolicy.NoRecursion 不支持,發現遞歸會拋異常。

LockRecursionPolicy.SupportsRecursion  即支持遞歸模式,線程鎖中繼續在使用鎖。

復制代碼 代碼如下:

cacheLock.EnterReadLock();
            //do
                cacheLock.EnterReadLock();
                //do
                cacheLock.ExitReadLock();
            cacheLock.ExitReadLock();

這種模式極易容易死鎖,比如讀鎖里面使用寫鎖。

復制代碼 代碼如下:

cacheLock.EnterReadLock();
            //do
              cacheLock.EnterWriteLock();
              //do
              cacheLock.ExitWriteLock();
            cacheLock.ExitReadLock();

下面是直接拿msdn的緩存例子了,加了簡單注釋。

復制代碼 代碼如下:

public class SynchronizedCache
    {
        private ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim();
        private Dictionary<int, string> innerCache = new Dictionary<int, string>();

        public string Read(int key)
        {
            //進入讀鎖,允許其他所有的讀線程,寫入線程被阻塞。
            cacheLock.EnterReadLock();
            try
            {
                return innerCache[key];
            }
            finally
            {
                cacheLock.ExitReadLock();
            }
        }

        public void Add(int key, string value)
        {
            //進入寫鎖,其他所有訪問操作的線程都被阻塞。即寫獨占鎖。
            cacheLock.EnterWriteLock();
            try
            {
                innerCache.Add(key, value);
            }
            finally
            {
                cacheLock.ExitWriteLock();
            }
        }

        public bool AddWithTimeout(int key, string value, int timeout)
        {
            //超時設置,如果在超時時間內,其他寫鎖還不釋放,就放棄操作。
            if (cacheLock.TryEnterWriteLock(timeout))
            {
                try
                {
                    innerCache.Add(key, value);
                }
                finally
                {
                    cacheLock.ExitWriteLock();
                }
                return true;
            }
            else
            {
                return false;
            }
        }

        public AddOrUpdateStatus AddOrUpdate(int key, string value)
        {
            //進入升級鎖。 同時只能有一個可升級鎖線程。寫鎖,升級鎖都被阻塞,但允許其他讀取數據的線程。
            cacheLock.EnterUpgradeableReadLock();
            try
            {
                string result = null;
                if (innerCache.TryGetValue(key, out result))
                {
                    if (result == value)
                    {
                        return AddOrUpdateStatus.Unchanged;
                    }
                    else
                    {
                        //升級成寫鎖,其他所有線程都被阻塞。
                        cacheLock.EnterWriteLock();
                        try
                        {
                            innerCache[key] = value;
                        }
                        finally
                        {
                            //退出寫鎖,允許其他讀線程。
                            cacheLock.ExitWriteLock();
                        }
                        return AddOrUpdateStatus.Updated;
                    }
                }
                else
                {
                    cacheLock.EnterWriteLock();
                    try
                    {
                        innerCache.Add(key, value);
                    }
                    finally
                    {
                        cacheLock.ExitWriteLock();
                    }
                    return AddOrUpdateStatus.Added;
                }
            }
            finally
            {
                //退出升級鎖。
                cacheLock.ExitUpgradeableReadLock();
            }
        }

        public enum AddOrUpdateStatus
        {
            Added,
            Updated,
            Unchanged
        };
    }

四:總結

多線程實際開發當中,往往測試沒問題,一到生產環境,并發高了就容易出問題, 一定注意。

本文參考CLR via C#。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91精品国产综合久久香蕉的用户体验| 成人女保姆的销魂服务| 日本久久久久久久| 欧美乱妇高清无乱码| 欧洲午夜精品久久久| 最新日韩中文字幕| 2020国产精品视频| 中文字幕免费国产精品| 欧美劲爆第一页| 亚洲欧美精品中文字幕在线| 国产精品福利网站| 日韩中文字幕在线观看| 精品国产乱码久久久久久虫虫漫画| 精品一区二区三区四区| 欧美精品日韩www.p站| 黑人精品xxx一区| 国产一区二区av| 国产精品欧美在线| 最近2019年好看中文字幕视频| 92版电视剧仙鹤神针在线观看| 国产欧美日韩亚洲精品| www.亚洲一区| 欧美一级黄色网| 成人a在线观看| 日韩电影在线观看免费| 精品无人国产偷自产在线| 欧美有码在线视频| 26uuu另类亚洲欧美日本老年| 亚洲成人网久久久| 国产精品激情av电影在线观看| 国产成人精品久久二区二区| 国产精品高潮呻吟久久av无限| 一区二区三区www| 欧美在线影院在线视频| 欧美激情久久久久| 国产精品视频自在线| 97视频在线观看免费高清完整版在线观看| 精品日韩视频在线观看| 国产精品成人观看视频国产奇米| 久久香蕉国产线看观看网| 国产在线高清精品| 成人欧美在线观看| 亚洲激情在线观看视频免费| 91av成人在线| 久久久免费精品| 日韩天堂在线视频| 欧美成人免费在线观看| 超碰精品一区二区三区乱码| 日韩女优人人人人射在线视频| 亚洲丝袜在线视频| 亚洲欧美日韩精品久久奇米色影视| 久久影视电视剧凤归四时歌| 中文字幕成人精品久久不卡| 亚洲男人天堂2023| 91天堂在线视频| 色综合影院在线| 亚洲精品国产精品自产a区红杏吧| 欧美精品中文字幕一区| 久久久在线免费观看| 91色在线视频| 91久久国产综合久久91精品网站| 亚洲精品综合久久中文字幕| 日韩一级裸体免费视频| 亚洲美女在线观看| 91高清在线免费观看| 欧美日韩一区二区免费视频| 亚洲第一网中文字幕| 欧美激情精品久久久久久免费印度| 日韩精品中文字幕有码专区| 成人性生交大片免费看视频直播| 久久免费国产视频| 欧美精品国产精品日韩精品| 亚洲激情在线观看视频免费| 国内精品400部情侣激情| 日本久久久久久久久久久| 97福利一区二区| 在线不卡国产精品| 久久中文字幕国产| 精品福利一区二区| 国产成人综合精品| 亚洲精品久久久久久久久| 中文字幕日韩电影| 国产视频观看一区| 亚洲国产私拍精品国模在线观看| 91国产精品电影| 亚洲全黄一级网站| 日韩中文字幕在线免费观看| 久久精品国产精品亚洲| 黑人精品xxx一区一二区| 久久精品夜夜夜夜夜久久| 国产亚洲aⅴaaaaaa毛片| 久久久久久久色| 国产69精品久久久久99| 96pao国产成视频永久免费| 国产一区二区三区直播精品电影| 成人天堂噜噜噜| 亚洲精品国偷自产在线99热| 日韩亚洲欧美成人| 欧美大片在线影院| 国产97在线|日韩| 国产精品成人免费电影| 欧美激情亚洲国产| 在线国产精品视频| 日韩电影网在线| 中文字幕视频在线免费欧美日韩综合在线看| 久久人人爽亚洲精品天堂| 黄色成人av网| 日韩久久精品电影| 97精品久久久| 亚洲免费高清视频| 理论片在线不卡免费观看| 2020久久国产精品| 欧美老少配视频| 国产精品视频成人| 欧美美最猛性xxxxxx| 色综合久久久久久中文网| 亚洲精品一区中文字幕乱码| 91精品国产91久久久久久不卡| 大荫蒂欧美视频另类xxxx| 亚洲国产欧美在线成人app| 97精品国产97久久久久久春色| 欧美视频精品一区| 欧美亚洲国产视频小说| 日韩三级成人av网| 久久精品91久久香蕉加勒比| 少妇av一区二区三区| 亚洲欧美在线磁力| 国产成人高清激情视频在线观看| 亚洲欧美制服综合另类| 国产精品日韩专区| 国产精品老牛影院在线观看| 最近2019中文字幕一页二页| 91精品国产自产在线老师啪| 亚洲欧美自拍一区| 亚洲人成毛片在线播放| 国产日本欧美一区二区三区在线| 国产日韩欧美另类| 欧美午夜视频在线观看| 亚洲第一页自拍| 久热爱精品视频线路一| 亚洲精品视频免费在线观看| 日韩中文字幕在线免费观看| 国产精品狠色婷| 亚洲男女自偷自拍图片另类| 精品美女永久免费视频| 久久精品青青大伊人av| 色yeye香蕉凹凸一区二区av| 亚洲最大福利网站| 97热在线精品视频在线观看| 欧美精品国产精品日韩精品| 久久久视频在线| 久久精品视频99| 欧美精品性视频| 亚洲在线视频福利| 日韩中文在线视频| 一区二区欧美在线| 大胆欧美人体视频| 亚洲国产精品久久久| 国产ts一区二区| 亚洲欧美日韩视频一区| 色青青草原桃花久久综合| 亚洲毛片一区二区| 国产精品综合网站| 久久精品这里热有精品|