通过 channel 或 context 实现协程等待
如何让主协程等待多个子协程完成?这类似于 sync.wtgroup 的功能。
使用 channel
可以通过 channel 实现协程等待。示例代码如下:
// main.go package main import ( "fmt" "math/rand" "time" ) func main() { num := 10 ch := make(chan int, num) for i := 0; i < num; i++ { go func(ch chan int, key int) { fmt.println("goroutine start: ", key) t := rand.intn(5) + 1 time.sleep(time.duration(t) * time.second) fmt.println("goroutine end: ", key) // 为了不使 goroutine 阻塞,chan 创建时加了缓冲量 ch <- key }(ch, i) } fmt.println("main start") for i := 0; i < num; i++ { key := <-ch fmt.println("main get: ", key) } fmt.println("main end") }
登录后复制
使用 context
也可以通过 context 实现协程等待,示例代码如下:
// main.go package main import ( "context" "fmt" "math/rand" "time" ) func main() { num := 10 ctx, cancel := context.WithCancel(context.Background()) for i := 0; i < num; i++ { go func(ctx context.Context, key int) { fmt.Println("goroutine start: ", key) t := rand.Intn(5) + 1 time.Sleep(time.Duration(t) * time.Second) fmt.Println("goroutine end: ", key) // 当主协程调用 cancel 方法后,goroutine 会自行退出 cancel() }(ctx, i) } fmt.Println("main start") // 等待所有的 goroutine 执行完毕 <-ctx.Done() fmt.Println("main end") }
登录后复制
以上就是如何使用 Channel 或 Context 实现协程等待,使主协程等待多个子协程完成?的详细内容,更多请关注php中文网其它相关文章!