Go xml.Marshal发生数据竞争
当我在结构上使用xml.Marshal时,报告了一个奇怪的数据竞赛。我99%确信我没有发送相同的变量或类似的东西-相反,我会出现间歇性错误,其中封送处理函数认为它导致了数据竞争 这里的代码稍微简化了一点,但所有功能元素都存在:Go xml.Marshal发生数据竞争,go,Go,当我在结构上使用xml.Marshal时,报告了一个奇怪的数据竞赛。我99%确信我没有发送相同的变量或类似的东西-相反,我会出现间歇性错误,其中封送处理函数认为它导致了数据竞争 这里的代码稍微简化了一点,但所有功能元素都存在: // this is run prior to any calls being sent to the below functions func Setup() (descriptor *serviceDescriptor) { descriptor = new(
// this is run prior to any calls being sent to the below functions
func Setup() (descriptor *serviceDescriptor) {
descriptor = new(serviceDescriptor)
wpChan := make(chan *Call)
for i := 1; i < 100; i++ {
go serviceWorker(wpChan)
}
descriptor.wpChan = wpChan
return
}
// called externally to initiate a call
func (s *serviceDescriptor) Add(c *Call) {
go s.makeCall(c)
}
// sends a call to the worker pool set up in the Setup() function
func (s *serviceDescriptor) makeCall(c *Call) {
cw := new(callwrapper)
cw.internal = new(etFullCall)
cw.internal.Calldata = c
/// this is a channel that the next function listens to
s.wpChan <- ct
// the result is sent back on a channel and processed here
}
// this is a function
func worker(wpChan chan *callwrapper) {
for cw := range wpChan {
v := new(Result)
// this is where the data race occurs.
byt, err := xml.Marshal(cw.internal)
// do stuff with the result down here
}
}
让我们来扮演php程序员!省略的代码中一定有什么东西是这场比赛的原因。@当然,这是可能的其中之一。我们已经努力确保每个运算都是幂等的。每个goroutine都在创建一个新的call结构,并且没有对它们进行进一步的操作。请告诉我您是否需要更多信息来帮助调试。阅读堆栈跟踪及其背后的代码,我90%确定这是误报。如果它是真的阳性,那么在不更改slice.c或重新实现xml编码器的情况下,您将无法修复它。您可以尝试复制一个小测试用例吗?至于实际的比赛,它看起来不像是来自encoding/xml的比赛。更可能的情况是,您正在向多个xml.Marshal传递一个指针。没有完整的代码就没有什么帮助。
WARNING: DATA RACE
Write by goroutine 115:
runtime.copy()
/usr/lib/go/src/pkg/runtime/slice.c:120 +0x0
encoding/xml.(*parentStack).push()
/usr/lib/go/src/pkg/encoding/xml/marshal.go:901 +0x2bd
encoding/xml.(*printer).marshalStruct()
/usr/lib/go/src/pkg/encoding/xml/marshal.go:819 +0x58c
encoding/xml.(*printer).marshalValue()
/usr/lib/go/src/pkg/encoding/xml/marshal.go:524 +0x12a8
encoding/xml.(*Encoder).Encode()
/usr/lib/go/src/pkg/encoding/xml/marshal.go:153 +0x83
encoding/xml.Marshal()
/usr/lib/go/src/pkg/encoding/xml/marshal.go:72 +0x9d
exacttarget.serviceWorker()
/service.go:94 +0x20e
Previous write by goroutine 114:
runtime.copy()
/usr/lib/go/src/pkg/runtime/slice.c:120 +0x0
encoding/xml.(*parentStack).push()
/usr/lib/go/src/pkg/encoding/xml/marshal.go:901 +0x2bd
encoding/xml.(*printer).marshalStruct()
/usr/lib/go/src/pkg/encoding/xml/marshal.go:819 +0x58c
encoding/xml.(*printer).marshalValue()
/usr/lib/go/src/pkg/encoding/xml/marshal.go:524 +0x12a8
encoding/xml.(*Encoder).Encode()
/usr/lib/go/src/pkg/encoding/xml/marshal.go:153 +0x83
encoding/xml.Marshal()
/usr/lib/go/src/pkg/encoding/xml/marshal.go:72 +0x9d
exacttarget.serviceWorker()
/service.go:94 +0x20e
Goroutine 115 (running) created at:
service.Setup()
/service.go:39 +0x112
/src.processSingleUser()
/main_test.go:405 +0xdf
/src.testAddLists()
/main_test.go:306 +0x1f2
Goroutine 114 (running) created at:
service.Setup()
/service.go:39 +0x112
/src.processSingleUser()
/main_test.go:405 +0xdf
src.testAddLists()
/main_test.go:306 +0x1f2