【问题标题】:Safe to read from shared data structure in goroutines without channels在没有通道的 goroutine 中安全地从共享数据结构中读取
【发布时间】:2020-10-18 16:24:41
【问题描述】:

我是 Golang 的新手,开始使用 goroutine。我很好奇在不使用通道或互斥锁的情况下从另一个 goroutine 写入的数据结构中读取是否安全。在下面的例子中,events 数组对 main 和 goroutine 是可见的,但 main 只读取它并且 goroutine 正在修改它。这被认为是安全的吗?

var events = []string{}

func main() {

    go func() {
        for {
            if len(events) > 30 {
                events = nil
            }
            event := "The time is now " + time.Now().String()
            events = append(events, event)
            time.Sleep(time.Millisecond * 200)
        }
    }()

    for {
        for i:=0; i < len(events); i++ {
            fmt.Println(events[i])
        }
        time.Sleep(time.Millisecond * 100)
        fmt.Println("--------------------------------------------------------")
    }
}

谢谢。

【问题讨论】:

  • 没有并发读写是安全的。这样的代码在每种情况下都是活泼且未定义的。

标签: go


【解决方案1】:

不,这绝对不安全。您应该围绕访问events 使用同步原语,或者重新设计以使用通道。

您的代码今天可能在特定架构/操作系统上运行良好,但它可能会因微小的更改和/或在另一个架构/操作系统上而意外中断。

尝试使用-race 运行您的代码以进行验证。你可能会看到WARNING: DATA RACE。

另见this answer。

【讨论】:

  • 谢谢。鉴于当前状态,您是对的,不会发生竞争条件。但是经过思考后,我意识到当 main 循环事件时很容易发生这种情况,如果我的事件列表足够长并且在循环期间发生上下文切换,则内存地址位置可能无效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-02
  • 2019-11-18
  • 1970-01-01
  • 1970-01-01
  • 2022-01-02
  • 1970-01-01
  • 2022-09-27
相关资源
最近更新 更多