可以安全地重用sync.WaitGroup吗? [英] Can sync.WaitGroup safely be reused?

查看:45
本文介绍了可以安全地重用sync.WaitGroup吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在调用 Wait()之后,可以重新使用 sync.WaitGroup 吗?

Can sync.WaitGroup be reused after Wait() is called?

func worker(who string, in <-chan int, wg *sync.WaitGroup) {
    for i := range in {
        fmt.Println(who, i)
        wg.Done()
    }
}

func main() {
    var wg sync.WaitGroup

    AIn := make(chan int, 1)
    BIn := make(chan int, 1)

    go worker("a:", AIn, &wg)
    go worker("b:", BIn, &wg)

    for i := 0; i < 4; i++ {
        wg.Add(2)
        AIn <- i
        BIn <- i
        wg.Wait()
        fmt.Println("main:", i)
    }
}

play.golang.org/p/QLsvA-b4Ae 运行正常,但是可以保证安全吗?文档没有这么说,但是也许我只是偏执.

This play.golang.org/p/QLsvA-b4Ae runs as expected, but is it guaranteed to be safe? The documentation doesn't say so, but maybe I'm just being paranoid.

推荐答案

是的,它很安全.实际上,它甚至比这更安全.您可以同时从多个goroutine中进行 Wait ,并根据您的使用情况互换 Add Done 调用.只要 Add 发生在 Wait 之前,您就应该是安全的.

Yes, it is safe. In fact, it is even safer than that. You can Wait from multiple goroutines concurrently, and interchange Add and Done calls as appropriate for your use case. As long as the Add happens before the Wait, you should be safe.

出于好奇,现在 WaitGroup 是通过互斥锁,两个int32s计数器和一个信号量实现的:

Just out of curiosity, right now the WaitGroup is implemented with a mutex, two int32s counters, and a semaphore:

type WaitGroup struct {
        m       Mutex
        counter int32
        waiters int32
        sema    *uint32
}

这也是一个有趣的测试:

This is also an interesting test:

var wg1, wg2 sync.WaitGroup
wg1.Add(1)
wg1.Done()
wg1.Wait()
fmt.Println(wg1 == wg2) // Prints true

最后,如果您发现这种使用方式有任何问题,请报告,因为这将是一个错误.

Finally, if you do find any issues with that kind of use, please report as it would be a bug.

这篇关于可以安全地重用sync.WaitGroup吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆