<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何寫(xiě)一段死鎖代碼

          共 3712字,需瀏覽 8分鐘

           ·

          2020-11-12 13:24

          如何寫(xiě)一段死鎖代碼

          Intro

          上次介紹了如何寫(xiě)一段代碼造成 StackOverflow ,今天來(lái)玩一下,看如何寫(xiě)一段代碼造成死鎖

          什么是死鎖

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

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

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

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

          預(yù)防死鎖方法:

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

          .NET 中的死鎖

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

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

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

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

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

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

          More

          使用鎖的一些注意事項(xiàng):

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

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

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

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

          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é)個(gè)
          回復(fù) 【訪客】學(xué)
          回復(fù) 【小程序】學(xué)獲取15套【入門(mén)+實(shí)戰(zhàn)+賺錢(qián)】小程序源碼
          回復(fù) 【python】學(xué)微獲取全套0基礎(chǔ)Python知識(shí)手冊(cè)
          回復(fù) 【2019】獲取2019 .NET 開(kāi)發(fā)者峰會(huì)資料PPT
          回復(fù) 【加群】加入dotnet微信交流群

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


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


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

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  豆花视频一区二区三区入口 | 国产啊v视频 | 色婷婷综合激情 | 豆花视频免费 | 91无码秘 在线无码观看蜜桃 |