doushang3352 2017-08-26 11:46
浏览 30

在这种情况下,WaitGroup.Wait()是否暗示内存屏障?

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?

There is a discussion of this question at the old go forum here: https://groups.google.com/forum/#!topic/golang-nuts/5oHzhzXCcmM The answer there was yes, it is safe. Then the discussion digress to use of atomic, etc., which is not what I want to ask about.

There is not even one mention of WaitGroup in the spec and it's documentation is saying WaitGroup.Wait: "Wait blocks until the WaitGroup counter is zero." which does not set any happens-before relationship (or does it?).

Does it mean that the first answer "It is safe to check condition after wg.Wait returns" is unofficial? If it's official what are the reasons for it I am missing? Thanks alot if you answer.

Update: This is update after @peterSO's @ravi's answers. Thanks.

Well, obviously there can be a race condition if you choose number of items > 1. Hint: condition can be set only to true. Still, I have the same question.

And probably, I should have stated that:

  1. underlying architectures can be only x86, x64 or ARM
  2. number of items can be 1

Update 2 I created followup question for the case when number of items == 1 here: Can you make this 'incorrectly synchronized' test fail?

  • 写回答

2条回答 默认 最新

  • dongzhang7157 2017-08-26 15:24
    关注

    Well, it is absolutely safe to check condition after wg.Wait(), but you should protect condition with a mutex to avoid it being "written to" simultaneously by multiple go routines. That's why @peterSO is hitting a race condition b'cos at line 20 in his code which is setting condition = true multiple go routines are trying to set condition at the same time. Here's a sample https://play.golang.org/p/o3v6s_2qsY with 20k go rountines.

    As a best practice I recommend, one adds defer wg.Done() right in the beginning of the go routine function, so that even if there are return statements in between, wg.Done() still gets called.

    评论

报告相同问题?

悬赏问题

  • ¥15 公交车和无人机协同运输
  • ¥15 stm32代码移植没反应
  • ¥15 matlab基于pde算法图像修复,为什么只能对示例图像有效
  • ¥100 连续两帧图像高速减法
  • ¥15 如何绘制动力学系统的相图
  • ¥15 对接wps接口实现获取元数据
  • ¥20 给自己本科IT专业毕业的妹m找个实习工作
  • ¥15 用友U8:向一个无法连接的网络尝试了一个套接字操作,如何解决?
  • ¥30 我的代码按理说完成了模型的搭建、训练、验证测试等工作(标签-网络|关键词-变化检测)
  • ¥50 mac mini外接显示器 画质字体模糊