go - 关于golang并发的问题

标签 go concurrency

我正在阅读官方文档,有一个我不懂的代码。

var a string
var done bool

func setup() {
    a = "hello, world"
    done = true
}

func doprint() {
    if !done {
        once.Do(setup)
    }
    print(a)
}

func twoprint() {
    go doprint()
    go doprint()
}

This version can (incorrectly) print an empty string instead of "hello, world".



为什么此代码可能会产生错误的结果。

最佳答案

因为在doprint()中,无需同步即可访问(读取)done变量。

想象一下,第一个goroutine运行doprint()在第二个goroutine计划运行之前完成了。第一个写入done(在setup()中),第二个goroutine尝试读取done:读取的结果应该产生第一个goroutine写入的结果吗?没有同步:未定义的行为。可能是done将被观察为true,因此将不会调用setup(),并且可能会是未观察到对a的写入,因此将打印初始零值(空字符串)。

变量的读取始终遵循单个goroutine中的先前写入(时间先前)。 goroutine所做的写入不能保证在另一个goroutine中得到观察,除非它们之间存在同步。

关于go - 关于golang并发的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60540573/

相关文章:

Golang CLI 眼镜蛇计数标志

go - 如何禁用 Golang 未使用的导入错误

go - 普罗米修斯自定义注册表不工作

go - 事件处理中的死锁

java - 异步NIO : Same client sending multiple messages to Server

scala - 如何等待多个 future ?

goroutine race condition 解决方案

go - 以编程方式检查 SPF、DKIM、DMARC

Java RMI 和同步方法

multithreading - 从不同的线程读取值