2015-02-06 53 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