sync.WaitGroup可以安全地重用吗?

huangapple go评论82阅读模式
英文:

Can sync.WaitGroup safely be reused?

问题

sync.WaitGroup在调用Wait()之后可以被重用。在你提供的代码示例中,sync.WaitGroup被重复使用,并且在每次循环迭代之前都调用了Add()方法来增加等待的数量。这是安全的做法,因为Wait()方法会等待所有的Done()方法被调用,然后解除阻塞。所以你不必担心在重用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)
	}
}

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.

答案1

得分: 29

是的,它是安全的。实际上,它甚至比那更安全。你可以同时从多个goroutine中使用Wait,并根据你的用例适当地交换AddDone调用。只要AddWait之前发生,你就应该是安全的。

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

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

这也是一个有趣的测试:

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

最后,如果你发现任何与这种用法有关的问题,请报告,因为那可能是一个bug。

英文:

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.

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.

huangapple
  • 本文由 发表于 2013年8月30日 09:18:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/18523425.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定