在这种情况下,WaitGroup.Wait()是否意味着内存障碍?

时间:2017-08-26 11:46:05

标签: go concurrency

var condition bool
var wg sync.WaitGroup
for _, item := range items {
    wg.Add(1)
    go func(item) {
        if meetsCondition(item) {
            condition = true
        }
        wg.Done()
    }(item)
}
wg.Wait()
// is it safe to check condition here?

在旧的论坛上有一个关于这个问题的讨论: https://groups.google.com/forum/#!topic/golang-nuts/5oHzhzXCcmM答案是肯定的,这是安全的。然后讨论离题使用原子等,这不是我想要问的。

规范中甚至没有提到WaitGroup,它的文档是说WaitGroup.Wait:"等待阻塞直到WaitGroup计数器为零。"哪个 没有设置任何发生在之前的关系(或者它?)。

这是否意味着第一个答案"在wg.Wait返回"之后检查条件是安全的。是非官方的?如果它的官方是什么原因我错过了?非常感谢,如果你回答。

更新 这是@ peterSO' s @ ravi的答案之后的更新。感谢。

嗯,如果您选择项目数量>显然可能存在竞争条件。 1.提示:条件只能设置为true。不过,我有同样的问题。

可能,我应该说:

  1. 底层架构只能是x86,x64或ARM
  2. 项目数量可以是1
  3. 更新2 当项目数量== 1时,我为案例创建了后续问题: Can you make this 'incorrectly synchronized' test fail?

2 个答案:

答案 0 :(得分:2)

是。 wg.Wait()wg.Done()之间存在关系发生的关系。这个简单的事实无论出于什么原因都没有在doc或MM #7948中提到。感谢Ian Lance Taylor澄清它golang-nuts/5oHzhzXCcmM。关于竞争条件,您可以在同一个帖子中阅读更多内容。

有点令人失望的是,在一种自称为并发语言的语言中,必须依赖一个“好词”'做基本的东西(右)。

答案 1 :(得分:1)

嗯,在condition之后检查wg.Wait()是绝对安全的,你应该使用互斥锁保护condition以避免被“写入”同时通过多个例行程序。这就是为什么@peterSO在他的代码中遇到第20行的竞争条件b'cos,设置condition = true多个go例程正在尝试同时设置condition。这是一个带有20k go rountines的样本https://play.golang.org/p/o3v6s_2qsY

作为我推荐的最佳实践,可以在go例程函数的开头添加defer wg.Done(),这样即使中间存在return语句,wg.Done()仍会被调用。