what is the proper way to use golang sync.WaitGroup

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

what is the proper way to use golang sync.WaitGroup

问题

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

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

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

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

var wg sync.WaitGroup      // 在全局范围内声明变量

func send(a string, b string){
    defer wg.Done()
    // 做一些事情
}
func main(){
    for i:=0; i<50; i++ {
         wg.Add(1)              // 增加delta
         go send("1111", "2222")
    }
    wg.Wait()                  // 等待直到wg变为0
}

非常感谢您的建议!

英文:

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?

var wg sync.WaitGroup      // declare the variable globally

func send(a string, b string){
    defer wg.Done()
    // do something
}
func main(){
    for i:=0; i&lt;50; i++ {
         wg.Add(1)              // add delta
         go send(&quot;1111&quot;, &quot;2222&quot;)
    }
    wg.Wait()                  // wait until wg becomes 0
}

Any suggestions are appreciate! Thanks!

答案1

得分: 2

这个例子可以帮助你:

var wg sync.WaitGroup
done := make(chan bool)

for _, element := range slice {
    wg.Add(1)
    go func(elem interface{}) {
        wg.Done()
    }(element)
}

go func() {
    wg.Wait()
    done <- true
}()

for {
    select {
    case <-done:
        fmt.Println("所有 goroutine 完成")
        close(done)
        return
    case <-time.After(time.Minute * 2):
        fmt.Println("超时!")
        return
    }
}

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

英文:

This example could help you

var wg sync.WaitGroup
done := make(chan bool)

for _, element := range slice {
	wg.Add(1)
	go func(elem interface{}) {
		wg.Done()
	}(element)
}

go func() {
	wg.Wait()
	done &lt;- true
}()

for {
	select {
	case done:
		fmt.Println(&quot;All goroutines completed&quot;)
		close(done)
		return
	case time.After(time.Minute * 2):
		fmt.Println(&quot;Timeout!&quot;)
		return
	}
}

答案2

得分: -1

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

package main

func send(a string, b string, c chan bool) {
//	println( a, b )
	c <- true;
}

func main() {

	c := make(chan bool)

	for i:=0; i<50; i++ {
		go send("1111", "2222", c)
	}

	w := 0
	for _ = range c {
		w += 1
		if w == 50 { break }
	}

}
英文:

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

package main

func send(a string, b string, c chan bool) {
//	println( a, b )
	c &lt;- true;
}

func
main() {

	c := make( chan bool )

	for i:=0; i&lt;50; i++ {
		go send(&quot;1111&quot;, &quot;2222&quot;, c)
	}

	w := 0
	for _ = range c {
		w += 1
		if w == 50 { break }
	}

}

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:

确定