sync.WaitGroup中要求Wait的时候不能Add,这样做的原因是什么呢?

kiwi-yan · 2017-09-27 03:09:34 · 1512 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2017-09-27 03:09:34 的主题,其中的信息可能已经有所发展或是发生改变。

理论上Wait的时候Add是可行的啊,Wait只需要关注当前数目是不是0就可以了啊


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1512 次点击  
加入收藏 微博
7 回复  |  直到 2017-09-28 07:24:28
legendlzy
legendlzy · #1 · 7年之前

哪里写了不能add? 一般场景不应该是wait的时候add吗?当所有gorouitne执行完才结束?

kiwi-yan
kiwi-yan · #2 · 7年之前

比如有两个goroutine,第一个里面有wg.Wait(),第二个里面有wg.Add(1),Add()比Wait()晚一些运行 就会报错 截图.png

kiwi-yan
kiwi-yan · #3 · 7年之前
legendlzylegendlzy #1 回复

哪里写了不能add? 一般场景不应该是wait的时候add吗?当所有gorouitne执行完才结束?

不好意思,恢复没有对准,你看看我在2L贴的图,是waitgroup里面的源码

polaris
polaris · #4 · 7年之前

@kiwi-yan 为啥不能贴代码呢?不会 markdown,看看这里的简明教程吧。

kiwi-yan
kiwi-yan · #5 · 7年之前
polarispolaris #4 回复

@kiwi-yan 为啥不能贴代码呢?不会 markdown,看看这里的[简明教程](/markdown)吧。

代码大致如下,是公司一个不成熟的框架,问题已经改掉了,现在想对这个原理探究一下

// 主逻辑
go Do()
<- a.close  // a是一个channel定义在其他位置,发现异常就会close掉
// 此时Do内可能才执行到DoSomething_1(), 所以会导致Wait以后执行Add,这个时候就会panic
wg.Wait()


// Do函数定义如下
func Do() {
    for {
        select {
            case <- a.close:
                return
            default:
                DoSomething_0()
                go func() {
                    DoSomething_1()
                    wg.Add(1)
                    go func() {
                        defer wg.Done()
                        DoSomething_2()
                    }()
                    DoSomething_3()
                }()
        }
    }
}
polaris
polaris · #6 · 7年之前

只是要求没有 Add 过之前,Add 正数不允许发生在 Wait 之前。http://docs.studygolang.com/pkg/sync/#WaitGroup.Add 文档有明确说明。

你这么理解:信号量都没有获取,怎么释放?必须现有 goroutine 获取了,才能等待释放。

legendlzy
legendlzy · #7 · 7年之前

不能在一进入函数就add吗?因为当wait调用的时候发现没有数据,就会报错。 源码注释里也有写 new Add calls must happen after all previous Wait calls have returned. 表达的不是说在wait的时候不能add,是表达要先add然后再调用wait

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传