鑒于下面的代碼,我試圖理解為什么 Go 競爭檢測器 ( go run -race example.go) 不會抱怨競爭條件。var count intfunc main() { http.HandleFunc("/a/", func(w http.ResponseWriter, r *http.Request) { count++ fmt.Println(count) }) http.HandleFunc("/b/", func(w http.ResponseWriter, r *http.Request) { count++ fmt.Println(count) }) log.Fatal(http.ListenAndServe(":8080", nil))}我的理解是 Go HTTP Server 在一個單獨的 goroutine 中響應所有請求??紤]到這一點,處理函數對全局計數變量所做的增量是否會發生在與主 goroutine 分開的 goroutine 中,從而構成數據競爭?如果這不是數據競賽,我非常想知道原因。
3 回答

皈依舞
TA貢獻1851條經驗 獲得超3個贊
這是一個競爭條件。種族檢查器可能會出現假陰性。
競態檢查器是動態的:它不會檢查問題的來源,它只能查看讀取和寫入是否實際發生,兩者之間沒有同步操作。您的代碼中沒有同步操作,但如果net/http
在增量之間發生了同步操作,它就會被愚弄。 它的作者建議,本質上,運行并發壓力測試來解決問題:
編寫好的并發測試
使用比賽檢測器進行連續構建
運行集成測試
在生產中運行支持競爭的金絲雀
在 Go 1.4 及以下版本中,您還應該確保您的程序在多個內核上運行,例如,runtime.GOMAXPROCS(runtime.NumCPU())
. 在 2015 年底左右發布的 Go 1.5 中,GOMAXPROCS 將默認在所有可用內核上運行您的代碼。

蠱毒傳說
TA貢獻1895條經驗 獲得超3個贊
count++
是一場數據競賽。它不會以原子方式發生。它與以下內容相同:
count = count + 1
如果比賽檢測器沒有看到它,您可能沒有足夠努力地訪問服務器。
- 3 回答
- 0 關注
- 249 瀏覽
添加回答
舉報
0/150
提交
取消