Go語言死鎖檢查工具:sync

jopen 10年前發布 | 49K 次閱讀 sync Google Go/Golang開發

Go語言死鎖檢查工具,可以輸出復雜的死鎖鏈條信息,誰等在哪里等待,誰在哪里鎖的,具體到行號,在不開啟死鎖檢查時不會影響程序性能,可直接替代原生sync包。

介紹

這個包用來在開發調試期,幫助排查程序中的死鎖情況。

用法

通常我們項目中引用到原生sync包的代碼會像這樣:

package myappimport "sync" var MyLock sync.Mutex func MyFunc() {
    MyLock.Lock()
    defer MyLock.Unlock()

    // ....... }

只需要將原來引用sync的代碼改為引用github.com/funny/sync包,不需要修改別的代碼:

package myappimport "github.com/funny/sync" var MyLock sync.Mutex func MyFunc() {
    MyLock.Lock()
    defer MyLock.Unlock()

    // ....... }

這時候死鎖診斷還沒有被啟用,因為做了條件編譯,所以鎖的開銷跟原生sync包是一樣的。

當需要編譯一個帶死鎖診斷的版本的時候,在go build --tags列表中加入deadlock標簽。

例如這樣:

go build -tags deadlock myproject

同樣這個標簽也用于單元測試,否則默認的單元測試會死鎖:

go test -tags deadlock -v

原理

在開啟死鎖檢查的時候,系統會維護一份全局的鎖等待列表,其次每個鎖都會有當前使用者的信息。

當一個goroutine要等待一個鎖的時候,系統會到全局的等待列表里面查找當前這個鎖的使用者,是否間接或直接的正在等待當前請求鎖的這個goroutine。

死鎖不一定只發生在兩個goroutine之間,極端情況也可能是一個鏈條狀的依賴關系,又或者可能出現自身重復加鎖的死鎖情況。

當出現死鎖的時候,系統將提取死鎖鏈上的所有goroutine的堆棧跟蹤信息,方便排查故障原因。

因為需要維護一份全局的鎖等待列表,所以這里會出現額外并且集中的一個全局鎖開銷,會導致明顯的程序的并發性能下降。

全局鎖的問題還會再繼續研究和加以改進,但是目前這個包是不能用于生產環境的,只能用在開發和調試期作為死鎖診斷的輔助工具。


項目主頁:http://www.baiduhome.net/lib/view/home/1417966810542

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!