context sample in golang

发布时间 2023-05-10 11:16:29作者: wallywl
package main

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

func routine(id int, ctx context.Context, msg chan int, wg *sync.WaitGroup) {

    defer wg.Done()

    fmt.Println("routine ", id)

    ticker := time.NewTicker(1 * time.Second)

    for range ticker.C {
        select {
        case <-ctx.Done():
            fmt.Println(ctx.Err(), id)
            return
        default:
            fmt.Println("recv msg ", id, <-msg)
        }
    }
}

func main() {
    var wg sync.WaitGroup

    msg := make(chan int, 10)

    //send msg
    for i := 0; i < 10; i++ {
        msg <- i
    }

    //ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(3*time.Second))
    ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
    //ctx, cancel := context.WithCancel(context.Background())

    defer cancel()

    for i := 1; i < 3; i++ {
        wg.Add(1)
        go routine(i, ctx, msg, &wg)
    }

    defer close(msg)

    //time.Sleep(3 * time.Second)
    //cancel()

    wg.Wait()

    fmt.Println("main exit")
}

    调用context 的WithCancel 方法时,需要主动调用cancel, 才能发送 Done,从而结束每个协程,而WithDeadline (WithTimeout 是对WithDeadline的封装) 因为有时间参数,不需要主动调用cancel.