Go 語言 競爭條件檢測

2023-03-14 16:58 更新

原文鏈接:https://gopl-zh.github.io/ch9/ch9-06.html


9.6. 競爭條件檢測

即使我們小心到不能再小心,但在并發(fā)程序中犯錯還是太容易了。幸運的是,Go的runtime和工具鏈為我們裝備了一個復(fù)雜但好用的動態(tài)分析工具,競爭檢查器(the race detector)。

只要在go build,go run或者go test命令后面加上-race的flag,就會使編譯器創(chuàng)建一個你的應(yīng)用的“修改”版或者一個附帶了能夠記錄所有運行期對共享變量訪問工具的test,并且會記錄下每一個讀或者寫共享變量的goroutine的身份信息。另外,修改版的程序會記錄下所有的同步事件,比如go語句,channel操作,以及對(*sync.Mutex).Lock(*sync.WaitGroup).Wait等等的調(diào)用。(完整的同步事件集合是在The Go Memory Model文檔中有說明,該文檔是和語言文檔放在一起的。譯注:https://golang.org/ref/mem )

競爭檢查器會檢查這些事件,會尋找在哪一個goroutine中出現(xiàn)了這樣的case,例如其讀或者寫了一個共享變量,這個共享變量是被另一個goroutine在沒有進(jìn)行干預(yù)同步操作便直接寫入的。這種情況也就表明了是對一個共享變量的并發(fā)訪問,即數(shù)據(jù)競爭。這個工具會打印一份報告,內(nèi)容包含變量身份,讀取和寫入的goroutine中活躍的函數(shù)的調(diào)用棧。這些信息在定位問題時通常很有用。9.7節(jié)中會有一個競爭檢查器的實戰(zhàn)樣例。

競爭檢查器會報告所有的已經(jīng)發(fā)生的數(shù)據(jù)競爭。然而,它只能檢測到運行時的競爭條件;并不能證明之后不會發(fā)生數(shù)據(jù)競爭。所以為了使結(jié)果盡量正確,請保證你的測試并發(fā)地覆蓋到了你的包。

由于需要額外的記錄,因此構(gòu)建時加了競爭檢測的程序跑起來會慢一些,且需要更大的內(nèi)存,即使是這樣,這些代價對于很多生產(chǎn)環(huán)境的程序(工作)來說還是可以接受的。對于一些偶發(fā)的競爭條件來說,讓競爭檢查器來干活可以節(jié)省無數(shù)日夜的debugging。(譯注:多少服務(wù)端C和C++程序員為此競折腰。)



以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號