what is the proper way to use golang sync.WaitGroup

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

what is the proper way to use golang sync.WaitGroup

问题

根据golang文档中的说明,sync包主要用于低级别的库例程。

除了Once和WaitGroup类型之外,大多数都是为低级别的库例程设计的。更高级别的同步最好通过通道和通信来完成。

我不太理解这个说法,我使用下面的示例来使用sync。
我的目的只是让主线程等待,直到所有其他线程完成,类似于C++线程库中的.join()。

问题:
1:像这样使用sync是否合适?还是应该使用通道而不是sync?
2:通道和sync之间有什么区别?

  1. var wg sync.WaitGroup // 在全局范围内声明变量
  2. func send(a string, b string){
  3. defer wg.Done()
  4. // 做一些事情
  5. }
  6. func main(){
  7. for i:=0; i<50; i++ {
  8. wg.Add(1) // 增加delta
  9. go send("1111", "2222")
  10. }
  11. wg.Wait() // 等待直到wg变为0
  12. }

非常感谢您的建议!

英文:

As mentioned in golang doc, sync is intent for low level library routines.
> Other than the Once and WaitGroup types, most are intended for use by
> low-level library routines. Higher-level synchronization is better
> done via channels and communication.

I am not quite understanding this statement and I use sync like the example below.
My purpose is just to let main thread wait until all the other threads finish, similar to .join() in c++ thread library.

Questions:
1: Is that proper to use sync like this? Or should I use channel instead of sync?
2: What is the difference between channel and sync?

  1. var wg sync.WaitGroup // declare the variable globally
  2. func send(a string, b string){
  3. defer wg.Done()
  4. // do something
  5. }
  6. func main(){
  7. for i:=0; i&lt;50; i++ {
  8. wg.Add(1) // add delta
  9. go send(&quot;1111&quot;, &quot;2222&quot;)
  10. }
  11. wg.Wait() // wait until wg becomes 0
  12. }

Any suggestions are appreciate! Thanks!

答案1

得分: 2

这个例子可以帮助你:

  1. var wg sync.WaitGroup
  2. done := make(chan bool)
  3. for _, element := range slice {
  4. wg.Add(1)
  5. go func(elem interface{}) {
  6. wg.Done()
  7. }(element)
  8. }
  9. go func() {
  10. wg.Wait()
  11. done <- true
  12. }()
  13. for {
  14. select {
  15. case <-done:
  16. fmt.Println("所有 goroutine 完成")
  17. close(done)
  18. return
  19. case <-time.After(time.Minute * 2):
  20. fmt.Println("超时!")
  21. return
  22. }
  23. }

这段代码展示了如何使用goroutine和channel来等待一组goroutine的完成,并设置超时机制。

英文:

This example could help you

  1. var wg sync.WaitGroup
  2. done := make(chan bool)
  3. for _, element := range slice {
  4. wg.Add(1)
  5. go func(elem interface{}) {
  6. wg.Done()
  7. }(element)
  8. }
  9. go func() {
  10. wg.Wait()
  11. done &lt;- true
  12. }()
  13. for {
  14. select {
  15. case done:
  16. fmt.Println(&quot;All goroutines completed&quot;)
  17. close(done)
  18. return
  19. case time.After(time.Minute * 2):
  20. fmt.Println(&quot;Timeout!&quot;)
  21. return
  22. }
  23. }

答案2

得分: -1

我不知道是否合适,但是下面的代码可以实现功能,而不使用较低级别的“同步”操作。

  1. package main
  2. func send(a string, b string, c chan bool) {
  3. // println( a, b )
  4. c <- true;
  5. }
  6. func main() {
  7. c := make(chan bool)
  8. for i:=0; i<50; i++ {
  9. go send("1111", "2222", c)
  10. }
  11. w := 0
  12. for _ = range c {
  13. w += 1
  14. if w == 50 { break }
  15. }
  16. }
英文:

I don't know whether it is proper, but code below does the trick without using lower level 'sync'.

  1. package main
  2. func send(a string, b string, c chan bool) {
  3. // println( a, b )
  4. c &lt;- true;
  5. }
  6. func
  7. main() {
  8. c := make( chan bool )
  9. for i:=0; i&lt;50; i++ {
  10. go send(&quot;1111&quot;, &quot;2222&quot;, c)
  11. }
  12. w := 0
  13. for _ = range c {
  14. w += 1
  15. if w == 50 { break }
  16. }
  17. }

huangapple
  • 本文由 发表于 2016年12月7日 04:28:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/41004262.html
匿名

发表评论

匿名网友

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

确定