如何在golang中创建真实的种族条件

问题描述 投票:1回答:1

问题描述

最近,我学会了选项-race来检查go中的比赛条件。完整的命令是go run -race xxx.go,它确实对我有很大帮助。但是在某些情况下(下面的代码),我认为检查结果是错误的,并尝试了很多方法(下面的我试图引起恐慌)来得到REAL恐慌,但是失败了因此,我想知道代码是否正确以及比赛检查是否错误,或者您可以修改我的代码,以使我真正地惊慌。非常感谢。代码

package main import "fmt" type myType struct { A int } func main(){ c:=make(chan bool) x := new(myType) go func(){ x = new(myType) // write to x c <- true }() _ = *x // read from x <-c fmt.Println("end") }

比赛检查结果

go run -race test.go

================== WARNING: DATA RACE Write at 0x00c00009c010 by goroutine 6: main.main.func1() /Users/yaodongen/test.go:12 +0x56 Previous read at 0x00c00009c010 by main goroutine: main.main() /Users/yaodongen/test.go:15 +0xe2 Goroutine 6 (running) created at: main.main() /Users/yaodongen/test.go:11 +0xd4 ================== end Found 1 data race(s) exit status 66

我的观点

我试图找到竞争情况报告的原因。在post(中文)中,它提到a = in64(0)操作不是原子的。例如,在一台32位计算机中,像int64这样的数据可能是64位长度,CPU可能会复制一半的数据并被其他中断。在以下代码(

证明golang副本不是原子的)中,我编写了代码来证明其正确。但就我而言,代码x = new(myType)是要复制一个指针值,我认为可以在一个CPU副本中完成。换句话说,该操作是原子操作,永远不会达到竞争状态。证明golang副本不是原子的

package main import "fmt" import "time" func main(){ var x = [...]int{1,1,1,1,1,1} c := make(chan int, 100) go func(){ for i:=0;;i++{ if i&1 == 0 { x = [...]int{2,2,2,2,2,2} // write to x }else{ x = [...]int{1,1,1,1,1,1} // write to x } c<-0 // let other goroutine see the change of x <-c } }() go func(){ for { d := x // read from x if d[0] != d[5] { fmt.Println(d) panic("error") // proved the copy operation is not atomic } c<-0 <-c } }() time.Sleep(time.Millisecond * 10000) fmt.Println("end") }

我很想惊慌

但是失败,如果存在竞争条件(错误的内存地址),代码将崩溃。

package main import "fmt" import "time" type myType struct { A int } func main(){ x := new(myType) c := make(chan int, 100) go func(){ for { x = new(myType) // write to x c<-0 <-c } }() for i:=0; i<4; i++{ go func(){ for { _ = *x // if exists a race condition, `*x` will visit a wrong memory address, and will panic c<-0 <-c } }() } time.Sleep(time.Second * 10) fmt.Println("end") }

问题描述最近,我学会了-race选项来检查go中的竞争条件是否存在。完整的命令是go run -racexxx.go。它确实对我有很大帮助。但是在某些情况下(代码...
pointers go concurrency race-condition goroutine
1个回答
3
投票
Go的种族检测永远不会产生误报。如果它告诉您有一场比赛,那么就有[一场]比赛。它可能无法识别所有种族(它们必须碰巧可以被检测到),但是发现的结果始终是肯定的(种族检测器中的错误未计数)。
© www.soinside.com 2019 - 2024. All rights reserved.