Go 围棋中的数据竞赛:为什么会发生在10-11ms以下?

Go 围棋中的数据竞赛:为什么会发生在10-11ms以下?,go,data-race,Go,Data Race,以下是我运行的代码: 主程序包 进口( “fmt” “时间” ) 常数延迟=9*时间毫秒 func main(){ n:=0 go func(){ 时间。睡眠(延迟) n++ }() fmt.Println(n) } 以下是我使用的命令: go run-比赛数据\u race\u demo.go 以下是我注意到的行为: 当延迟设置为9ms或更低时,总是检测到数据竞争(程序抛出发现1个数据竞争)) 当延迟设置为12ms或更高时,将永远不会检测到数据竞争(程序仅打印0) 当delay设置为10

以下是我运行的代码:

主程序包
进口(
“fmt”
“时间”
)
常数延迟=9*时间毫秒
func main(){
n:=0
go func(){
时间。睡眠(延迟)
n++
}()
fmt.Println(n)
}
以下是我使用的命令:

go run-比赛数据\u race\u demo.go
以下是我注意到的行为:

  • 延迟设置为9ms或更低时,总是检测到数据竞争(程序抛出
    发现1个数据竞争)
  • 延迟设置为12ms或更高时,将永远不会检测到数据竞争(程序仅打印
    0
  • delay
    设置为10到11ms时,数据竞争会间歇性发生(即,有时打印
    0
    ,有时抛出
    Found 1个数据竞争)
为什么在10-11ms左右会发生这种情况


如果有必要的话,我将在
darwin/amd64
上使用Go 1.16.3。他们不同步地访问
n
变量(其中一个是写变量):这是一种数据竞争

是否检测到此竞争取决于是否发生此racy访问,它不会等待其他非
main
goroutine完成

如果增加睡眠延迟,
main()
将在睡眠结束之前结束,并且不会等待
n++
racy写入发生,因此未检测到任何内容。如果睡眠时间短,短于
fmt.Prinln()
执行时间,则会发生并检测到快速写入

10毫秒没有什么特别的。这只是执行
fmt.Println()
并在您的环境中终止应用程序所需的大致时间。如果在
Println()
语句之前执行其他“冗长”任务,例如:

for i := 0; i < 5_000_000_000; i++ {
}
fmt.Println(n)
i:=0的
;i<5_000_000_000;i++{
}
fmt.Println(n)

即使在50毫秒睡眠的情况下也会检测到竞争(因为该循环将需要一些时间来执行,从而允许在
fmt.Println()
调用读取
n
之前进行racy写入,并终止应用程序)。(一个简单的
time.Sleep()
也可以,我只是不想让任何人得出错误的结论,认为他们以某种方式相互“互动”)

谢谢。但是,10毫秒有什么特别之处呢?@ManuManjunath 10毫秒没有什么特别之处。这只是执行
fmt.Println()
并在您的环境中终止您的应用程序所需的时间。在
fmt.Println
之前,您甚至不必做任何事情,只需允许goroutine在退出前运行即可显示比赛,即使您在读写之间等待了几秒钟。“延迟设置为12ms或更高,数据竞争永远不会被检测到”,这意味着什么也没有:竞争仍然存在。