首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Go中的数据竞赛:为什么它发生在10-11ms以下?

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

Stack Overflow用户
提问于 2021-05-21 12:14:46
回答 1查看 105关注 0票数 4

下面是我运行的代码:

代码语言:javascript
运行
复制
package main

import (
    "fmt"
    "time"
)

const delay = 9 * time.Millisecond

func main() {
    n := 0
    go func() {
        time.Sleep(delay)
        n++
    }()
    fmt.Println(n)
}

下面是我使用的命令:

代码语言:javascript
运行
复制
go run -race data_race_demo.go

下面是我注意到的行为:

设置为9 is或更低的Found 1 data race(s))

  • With

  • ,总是检测到数据竞争(程序将Found 1 data race(s))

delay设置为12 is或更高,数据竞争永远不会被检测到)(程序只需打印10到11 is设置的0)

  • With delay,数据竞争就会间歇性地发生(有时打印0,有时会抛出Found 1 data race(s))

)。

为什么这种情况发生在大约10-11 10的上?

如果这重要的话,我在darwin/amd64上使用Go 1.16.3。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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()语句之前执行其他“冗长”任务,如下所示:

代码语言:javascript
运行
复制
for i := 0; i < 5_000_000_000; i++ {
}
fmt.Println(n)

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

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67636634

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档