2015-02-06 33 views
3

當我嘗試在2個或更多GoRoutine中將Struct編碼到XML時,我正在獲取數據爭用條件。golang競爭條件 - 在2個例程中封送到XML

樣品主程序:http://play.golang.org/p/YhkWXWL8C0

我相信xml:"members>member"導致此。如果我將其更改爲正常,那麼一切正常。任何想法爲什麼去1.4.x版本這樣做。

Family struct { 
    XMLName xml.Name `xml:"family"` 
    Name string `xml:"famil_name"` 
    Members []Person `xml:"members>member"` 
    //Members []Person `xml:"members"` 
} 

去data_race.go給我

2015/02/06 13:53:43 Total GoRoutine Channels Created 2 
2015/02/06 13:53:43 <family><famil_name></famil_name><members><person><name>ABCD</name><age>0</age></person><person><name>dummy</name><age>0</age></person></members></family> 
================== 
WARNING: DATA RACE 
Write by goroutine 6: 
    runtime.slicecopy() 
     /usr/local/go/src/runtime/slice.go:94 +0x0 
    encoding/xml.(*parentStack).push() 
     /usr/local/go/src/encoding/xml/marshal.go:908 +0x2fb 
    encoding/xml.(*printer).marshalStruct() 
     /usr/local/go/src/encoding/xml/marshal.go:826 +0x628 
    encoding/xml.(*printer).marshalValue() 
     /usr/local/go/src/encoding/xml/marshal.go:531 +0x1499 
    encoding/xml.(*Encoder).Encode() 
     /usr/local/go/src/encoding/xml/marshal.go:153 +0xb8 
    encoding/xml.Marshal() 
     /usr/local/go/src/encoding/xml/marshal.go:72 +0xfb 
    main.ToXml() 
     /Users/kadalamittai/selfie/go/src/github.com/ivam/goal/command/data_race.go:51 +0x227 
    main.func·001() 
     /Users/kadalamittai/selfie/go/src/github.com/ivam/goal/command/data_race.go:61 +0x74 

Previous read by goroutine 5: 
    encoding/xml.(*parentStack).trim() 
     /usr/local/go/src/encoding/xml/marshal.go:893 +0x2ae 
    encoding/xml.(*printer).marshalStruct() 
     /usr/local/go/src/encoding/xml/marshal.go:836 +0x203 
    encoding/xml.(*printer).marshalValue() 
     /usr/local/go/src/encoding/xml/marshal.go:531 +0x1499 
    encoding/xml.(*Encoder).Encode() 
     /usr/local/go/src/encoding/xml/marshal.go:153 +0xb8 
    encoding/xml.Marshal() 
     /usr/local/go/src/encoding/xml/marshal.go:72 +0xfb 
    main.ToXml() 
     /Users/kadalamittai/selfie/go/src/github.com/ivam/goal/command/data_race.go:51 +0x227 
    main.func·001() 
     /Users/kadalamittai/selfie/go/src/github.com/ivam/goal/command/data_race.go:61 +0x74 

Goroutine 6 (running) created at: 
    main.AsyncExecute() 
     /Users/kadalamittai/selfie/go/src/github.com/ivam/goal/command/data_race.go:67 +0x15d 
    main.main() 
     /Users/kadalamittai/selfie/go/src/github.com/ivam/goal/command/data_race.go:80 +0x2bf 

Goroutine 5 (finished) created at: 
    main.AsyncExecute() 
     /Users/kadalamittai/selfie/go/src/github.com/ivam/goal/command/data_race.go:67 +0x15d 
    main.main() 
     /Users/kadalamittai/selfie/go/src/github.com/ivam/goal/command/data_race.go:80 +0x2bf 
================== 
+0

這將有助於創建一個MCVE(請參閱stackoverflow.com/help/mcve)。這會給我們找到問題的更好機會。 – topskip 2015-02-06 20:40:16

回答

2

這看起來像在圍棋1.41庫中的缺陷運行-RACE。我已經報道過as a bug。希望它應該得到修復。我將留下以下分析以供參考。


發生了什麼事是,有一個隱含的共享值因使用的getTypeInfo()它返回該結構的一個類型描述。爲了提高效率,它似乎是全球緩存的狀態。 XML編碼器的其他部分使用這種狀態的組件並傳遞它。看起來,由於共享值的組成部分上的append片段發生了無意的突變。

p.stack屬性,該屬性的報告作爲數據種族的源從typeInfo共享值,其中的tinfo.parents切片得到上line 821注入的一部分起源。這最終是共享發生在讀取和寫入的潛力的地方,因爲稍後有片段上會發生appends,並且可以在底層陣列上進行突變。

可能發生的情況應該是容量限制,以便任何潛在的append都不會對共享數組值寫入數據。

也就是說,編碼器庫線897也許可以改變來自:

897  s.stack = parents[:split] 

到:

897  s.stack = parents[:split:split] 

來解決此問題。

+0

修復當前正在通過代碼審查。 https://go-review.googlesource.com/#/c/4152 – dyoo 2015-02-07 02:27:20

+0

試試[codereview.se]! – 2015-02-07 04:14:49

+0

謝謝@dyoo我正在檢查golang團隊的bug-id和代碼審查過程。感謝。 – kadalamittai 2015-02-08 16:14:00