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。不过,我有同样的问题。
可能,我应该说:
更新2 当项目数量== 1时,我为案例创建了后续问题: Can you make this 'incorrectly synchronized' test fail?
答案 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()
仍会被调用。