如何使用 Channel 或 Context 实现协程等待,使主协程等待多个子协程完成?

如何使用 channel 或 context 实现协程等待,使主协程等待多个子协程完成?

通过 channel 或 context 实现协程等待

如何让主协程等待多个子协程完成?这类似于 sync.waitgroup 的功能。

使用 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 实现协程等待,使主协程等待多个子协程完成?的详细内容,更多请关注其它相关文章!