Go by Example: WaitGroups

英文源地址
为了等待多个goroutine完成, 我们可以使用WaitGroup.

package main

import (
	"fmt"
	"sync"
	"time"
)

// 这个函数我们将在每个goroutine中运行
func worker(id int) {
    
    
	fmt.Printf("Worker %d starting\n", id)
	time.Sleep(time.Second)
	fmt.Printf("Worker %d done\n", id)
}

func main() {
    
    
	// 这个WaitGroup用于等待这里启动的所有协程完成.
	// 注意: 如果WaitGroup显式地传递给函数, 它应该通过指针进行.
	var wg sync.WaitGroup

	// 启动几个协程, 并为每个协程在WaitGroup计数器中进行增加
	for i := 1; i <= 5; i++ {
    
    
		wg.Add(1)

		// 避免在每个协程闭包中重复使用相同的值.具体细节可以参考FAQ
		i := i

		// 将worker调用包装在闭包中, 确保告诉WaitGroup这个worker已经完成.
		// 这样, 工作协程不必直到其执行中涉及的并发原语.
		go func() {
    
    
			defer wg.Done()
			worker(i)
		}()
	}
	// 阻塞, 直到WaitGroup计数器返回0;所有worker都通知已完成.
	wg.Wait()
	// 请注意, 这种方法没有直接的方法从worker中传递error.对于更进阶的用例, 请参考errgroup包.
}
$ go run waitgroups.go
Worker 5 starting
Worker 3 starting
Worker 4 starting
Worker 1 starting
Worker 2 starting
Worker 4 done
Worker 1 done
Worker 2 done
Worker 5 done
Worker 3 done

对于每次调用, worker协程的启动和结束顺序可能不一样.
下一节将介绍: Rate Limiting速率控制.

猜你喜欢

转载自blog.csdn.net/weixin_43547795/article/details/130872840
今日推荐