下面是我运行的代码:
package main
import (
"fmt"
"time"
)
const delay = 9 * time.Millisecond
func main() {
n := 0
go func() {
time.Sleep(delay)
n++
}()
fmt.Println(n)
}下面是我使用的命令:
go run -race data_race_demo.go下面是我注意到的行为:
设置为9 is或更低的Found 1 data race(s))
Found 1 data race(s))
delay设置为12 is或更高,数据竞争永远不会被检测到)(程序只需打印10到11 is设置的0)
delay,数据竞争就会间歇性地发生(有时打印0,有时会抛出Found 1 data race(s)))。
为什么这种情况发生在大约10-11 10的上?
如果这重要的话,我在darwin/amd64上使用Go 1.16.3。
发布于 2021-05-21 12:17:02
你有两个大猩猩:main和你发射的那个。它们不同步地访问n变量(其中一个是写的):这是一种数据竞争。
是否检测到此争用取决于是否发生此动态访问。When the main() function ends, your app ends as well,它不会等待其他非main的大杂烩完成。
如果您增加了睡眠延迟,main()将比睡眠结束更早结束,并且不会等待n++ racy写入发生,因此不会检测到任何东西。如果睡眠时间较短,且短于fmt.Prinln()执行时间,则会发生racy写入并检测到。
这10毫秒没有什么特别之处。这只是在您的环境中执行fmt.Println()和终止应用程序所需的大约时间。如果在Println()语句之前执行其他“冗长”任务,如下所示:
for i := 0; i < 5_000_000_000; i++ {
}
fmt.Println(n)即使在50 is睡眠的情况下也会检测到竞争(因为这个循环将需要一些时间来执行,允许在n被读取到fmt.Println()调用和应用程序终止之前就开始写)。(一个简单的time.Sleep()也可以,我只是不希望任何人得出错误的结论,认为他们以某种方式“互动”。)
https://stackoverflow.com/questions/67636634
复制相似问题