这是我运行的代码:package mainimport ( "fmt" "time")const delay = 9 * time.Millisecondfunc main() { n := 0 go func() { time.Sleep(delay) n++ }() fmt.Println(n)}这是我使用的命令:go run -race data_race_demo.go以下是我注意到的行为:设置为 9ms 或更低时,始终会检测到数据争用(程序抛出delayFound 1 data race(s))设置为 12ms 或更高时,永远不会检测到数据竞速(程序只是打印delay0)设置为 10 到 11 毫秒时,数据争用会间歇性地发生(即,有时打印,有时抛出delay0Found 1 data race(s))为什么这种情况发生在10-11ms左右?我正在使用Go 1.16.3,如果这很重要的话。darwin/amd64
1 回答
开满天机
TA贡献1786条经验 获得超13个赞
你有2个哥律:和你启动的那个。他们在没有同步的情况下访问变量(一个是写入):这是一场数据竞赛。mainn
是否检测到此种族取决于是否发生此不雅访问。当 main() 函数结束时,你的应用也会结束,它不会等待其他非 goroutine 完成。main
如果增加睡眠延迟,将比睡眠结束更早结束,并且不会等待不雅的写入发生,因此不会检测到任何内容。如果睡眠时间较短,短于执行时间,则会发生不雅的写入并被检测到。main()n++fmt.Prinln()
10ms没什么特别的。这只是在您的环境中执行和终止应用所需的大致时间。如果在语句之前执行其他“冗长”的任务,例如:fmt.Println()Println()
for i := 0; i < 5_000_000_000; i++ {
}
fmt.Println(n)即使睡眠时间为 50 毫秒,也会检测到比赛(因为该循环需要一些时间来执行,从而允许在读取调用和应用终止之前发生不雅的写入)。(一个简单的方法也可以,我只是不希望任何人得出错误的结论,即他们以某种方式“互动”彼此。nfmt.Println()time.Sleep()
- 1 回答
- 0 关注
- 100 浏览
添加回答
举报
0/150
提交
取消
