Go語言死鎖檢查工具:sync
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的堆棧跟蹤信息,方便排查故障原因。
因為需要維護一份全局的鎖等待列表,所以這里會出現額外并且集中的一個全局鎖開銷,會導致明顯的程序的并發性能下降。
全局鎖的問題還會再繼續研究和加以改進,但是目前這個包是不能用于生產環境的,只能用在開發和調試期作為死鎖診斷的輔助工具。
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!