日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

如何写一段死锁代码

發(fā)布時間:2023/12/4 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何写一段死锁代码 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

如何寫一段死鎖代碼

Intro

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

什么是死鎖

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

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

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

  • 互斥條件:進程要求對所分配的資源進行排它性控制,即在一段時間內(nèi)某資源僅為一進程所占用。

  • 請求和保持條件:當進程因請求資源而阻塞時,對已獲得的資源保持不放。

  • 不剝奪條件:進程已獲得的資源在未使用完之前,不能剝奪,只能在使用完時由自己釋放。

  • 環(huán)路等待條件:在發(fā)生死鎖時,必然存在一個進程--資源的環(huán)形鏈。

  • 預防死鎖方法:

    • 資源一次性分配:一次性分配所有資源,這樣就不會再有請求了:(破壞請求條件)

    • 只要有一個資源得不到分配,也不給這個進程(線程)分配其他的資源:(破壞請保持條件)

    • 可剝奪資源:即當某進程獲得了部分資源,但得不到其它資源,則釋放已占有的資源(破壞不可剝奪條件)

    • 資源有序分配法:系統(tǒng)給每類資源賦予一個編號,每一個進程按編號遞增的順序請求資源,釋放則相反(破壞環(huán)路等待條件)

    .NET 中的死鎖

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

    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 方法中會再次嘗試獲取鎖,此時因為鎖已經(jīng)被 Test 方法獲取而且并沒有釋放,所以會一直獲取不到鎖從而造成死鎖

    其實這種情況還有很多變形,比如說 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");} }

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

    More

    使用鎖的一些注意事項:

  • 鎖要用來鎖定對應的訪問資源,不同的資源使用不同的鎖來訪問限制

  • 鎖盡可能使用這樣的格式 private readonly object _locker = new object();,是否使用 static 根據(jù)需要添加,多個資源有關(guān)聯(lián)時,小心死鎖的情況,一次全部分配,任意一個資源分配失敗釋放另外一個鎖以避免死鎖

  • 實現(xiàn)分布式鎖的時候指定最大嘗試時間,避免死鎖避免長時間獲取不到鎖影響系統(tǒng)性能

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

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

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

    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

    總結(jié)

    以上是生活随笔為你收集整理的如何写一段死锁代码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。