1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        如何寫一段死鎖代碼

        共 3712字,需瀏覽 8分鐘

         ·

        2020-11-12 13:24

        如何寫一段死鎖代碼

        Intro

        上次介紹了如何寫一段代碼造成 StackOverflow ,今天來玩一下,看如何寫一段代碼造成死鎖

        什么是死鎖

        首先我們需要明確一下什么是死鎖,造成死鎖需要滿足哪些條件,知道這些就可以輕松寫出一段死鎖代碼了

        死鎖 是指兩個或兩個以上的進(jìn)程(線程)在執(zhí)行過程中,由于競爭資源或者由于彼此通信而造成的一種阻塞的現(xiàn)象,若無外力作用,它們都將無法推進(jìn)下去。此時稱系統(tǒng)處于死鎖 狀態(tài)或系統(tǒng)產(chǎn)生了死鎖,這些永遠(yuǎn)在互相等待的進(jìn)程稱為死鎖 進(jìn)程(線程)。  ---- 百度百科

        產(chǎn)生死鎖的必要條件:

        1. 互斥條件:進(jìn)程要求對所分配的資源進(jìn)行排它性控制,即在一段時間內(nèi)某資源僅為一進(jìn)程所占用。
        2. 請求和保持條件:當(dāng)進(jìn)程因請求資源而阻塞時,對已獲得的資源保持不放。
        3. 不剝奪條件:進(jìn)程已獲得的資源在未使用完之前,不能剝奪,只能在使用完時由自己釋放。
        4. 環(huán)路等待條件:在發(fā)生死鎖時,必然存在一個進(jìn)程--資源的環(huán)形鏈。

        預(yù)防死鎖方法:

        • 資源一次性分配:一次性分配所有資源,這樣就不會再有請求了:(破壞請求條件)
        • 只要有一個資源得不到分配,也不給這個進(jìn)程(線程)分配其他的資源:(破壞請保持條件)
        • 可剝奪資源:即當(dāng)某進(jìn)程獲得了部分資源,但得不到其它資源,則釋放已占有的資源(破壞不可剝奪條件)
        • 資源有序分配法:系統(tǒng)給每類資源賦予一個編號,每一個進(jìn)程按編號遞增的順序請求資源,釋放則相反(破壞環(huán)路等待條件)

        .NET 中的死鎖

        通常的死鎖的示例都是兩個鎖,多個資源導(dǎo)致的死鎖,你有沒有想過一個資源也會導(dǎo)致死鎖,如何使用一個鎖造成死鎖呢?思考一下再看下面的代碼

        private static readonly object Lock = new object();

        public static void Test()
        {
            lock (Lock)
            {
                Task.Run(TestMethod1).Wait();
            }
        }

        private static void TestMethod1()
        {
            lock (Lock)
            {
                Console.WriteLine("xxx");
            }
        }

        Test 這個方法中首先獲取鎖,獲取鎖成功之后調(diào)用另外一個線程去調(diào)用 TestMethod1 方法,而 TestMethod1 方法中會再次嘗試獲取鎖,此時因?yàn)殒i已經(jīng)被 Test 方法獲取而且并沒有釋放,所以會一直獲取不到鎖從而造成死鎖

        其實(shí)這種情況還有很多變形,比如說 lock(this)/lock("lockedString") 這種都是比較危險的,所以不推薦使用,我們使用上面的示例做一個變形,使用 lock("lockedString") 來測試一下

        public static void Test()
        {
            lock ("Lock")
            {
                Task.Run(TestMethod1).Wait();
            }
        }

        private static void TestMethod1()
        {
            lock ("Lock")
            {
                Console.WriteLine("xxx");
            }
        }

        這樣也會造成死鎖,因?yàn)?lock 的 string 實(shí)際上是同一個引用,字符串池(string intern),所以類似于上面的示例,相當(dāng)于是一個鎖,對于 lock(this) 也是類似的,所以通常 lock 是不推薦 lock(this)/lock("string") 這些寫法的,對于不同的資源要使用不同的 lock,這樣就可以避免上面這個示例的這種情況

        More

        使用鎖的一些注意事項:

        1. 鎖要用來鎖定對應(yīng)的訪問資源,不同的資源使用不同的鎖來訪問限制
        2. 鎖盡可能使用這樣的格式 private readonly object _locker = new object();,是否使用 static 根據(jù)需要添加,多個資源有關(guān)聯(lián)時,小心死鎖的情況,一次全部分配,任意一個資源分配失敗釋放另外一個鎖以避免死鎖
        3. 實(shí)現(xiàn)分布式鎖的時候指定最大嘗試時間,避免死鎖避免長時間獲取不到鎖影響系統(tǒng)性能

        在 SQL Server 中會有一個獨(dú)立的死鎖檢測的進(jìn)程,如果發(fā)生死鎖的情況,會有一個事務(wù)會被選擇為犧牲品來解決死鎖的問題

        在通過 Redis 實(shí)現(xiàn)分布式鎖的時候,通常會指定一個鎖的過期時間,過期時間通常是為了避免獲取鎖成功的系統(tǒng)突然宕機(jī)導(dǎo)致鎖一直在鎖定狀態(tài),從而導(dǎo)致其他服務(wù)獲取鎖的時候一直獲取失敗,除此之外,通常還會指定一個最大等待時間,如果別的服務(wù)獲取到鎖了,正在操作,那么會等待鎖釋放,但是為了避免死鎖,如果長時間獲取不到鎖的話就會放棄獲取鎖,直接返回獲取鎖失敗。

        除此之外你還了解哪些使用鎖的注意事項和避免死鎖的常用方法呢,歡迎補(bǔ)充,如果文中有誤,歡迎指出,萬分感謝。

        Reference

        • https://baike.baidu.com/item/死鎖/2196938
        • https://blog.csdn.net/hd12370/article/details/82814348
        • https://github.com/WeihanLi/SamplesInPractice/blob/master/StupidSamples/DeadLockSample.cs
        回復(fù) 【關(guān)閉】學(xué)關(guān)
        回復(fù) 【實(shí)戰(zhàn)】獲取20套實(shí)戰(zhàn)源碼
        回復(fù) 【被刪】學(xué)
        回復(fù) 【訪客】學(xué)
        回復(fù) 【小程序】學(xué)獲取15套【入門+實(shí)戰(zhàn)+賺錢】小程序源碼
        回復(fù) 【python】學(xué)微獲取全套0基礎(chǔ)Python知識手冊
        回復(fù) 【2019】獲取2019 .NET 開發(fā)者峰會資料PPT
        回復(fù) 【加群】加入dotnet微信交流群

        副業(yè)剛需,沒有人能拒絕這個網(wǎng)站!


        微信錢包“免費(fèi)提現(xiàn)”的方法來了!


        瀏覽 28
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            盗摄精品av一区二区三区 | 老女人操逼视频 | 8050午夜一级少妇电影院 | 啊啊啊轻点不要 | 午夜精品一区二区三区福利视频 | 欧洲无人区卡一卡二卡三 | 青草精品视频 | 撸一撸在线视频 | 国产农村寡妇高潮的毛片 | 妈妈太棒了插曲 |