为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕哥9229398 2022-09-26 14:16:08
这是我运行的代码: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()


查看完整回答
反对 回复 2022-09-26
  • 1 回答
  • 0 关注
  • 100 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号