以下演示示例以簡單的方式顯示了我已定義的內容。我將一個映射作爲一個複製值傳遞給一個函數(而不是一個引用),以及在我的函數中存在一個遞歸,我也假設這個遞歸也是通過了值的。併發映射在沒有併發時進行讀寫
https://play.golang.org/p/na6y6Wih4M
// this function has no write operations to dataMap, just reads
// dataMap, in fact, has no write operations since it was copied
func findParentAncestors(ID int, dataMap map[int]Data) []Data {
results := []Data{}
if _, ok := dataMap[ID]; ok {
if parentData, ok := dataMap[dataMap[ID].ParentID]; ok {
results = append(results, parentData)
// recursion
results = append(results, findParentAncestors(parentData.ID, dataMap)...)
}
}
return results
}
問題:不知何故沿着我的程序執行,其中涉及超過這個例子(obviusly)更多的數據,錯誤「致命錯誤:併發的地圖閱讀和地圖寫」點功能findParentAncestors():
main.findParentAncestors(0x39e3, 0xc82013ac90, 0x0, 0x0, 0x0)
/opt/test/src/test.go:17 +0xa6 fp=0xc820269fb8 sp=0xc820269bd0
main.findParentAncestors(0x5d25, 0xc82013ac90, 0x0, 0x0, 0x0)
/opt/test/src/test.go:21 +0x239 fp=0xc82026a3a0 sp=0xc820269fb8
Go是什麼版本?那堆棧跟蹤完成了嗎? – hobbs
go版本go1.6.3 linux/amd64 由於各種併發性,堆棧跟蹤非常大。 interst(恐慌的頂部)的部分就是上面的。 dataMap是按值傳遞的。我認爲這不會導致併發問題。 – gextra
我在這裏添加了完整的跟蹤https://play.golang.org/p/p75UITydVP – gextra