请教 context.WithTimeout 的正确用法

nfwater · · 3703 次点击
```go package main import ( "context" "fmt" "sync" "time" ) var wg sync.WaitGroup func main() { ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() go func() { wg.Add(2) go watch(ctx, 1) go watch(ctx, 2) wg.Wait() }() select { case <-ctx.Done(): fmt.Printf("watch %d %s\n", 0, ctx.Err()) } fmt.Println("finished") } func watch(ctx context.Context, flag int) { defer wg.Done() func() { fmt.Printf("doing something flag:%d\n", flag) time.Sleep(50 * time.Second) fmt.Println("finished flag:", flag) }() } ``` * 以上改法就可以实现你说的退出 * 你的写法程序会在 wg.wait() 上停住,等待两个协程结束,所以你的写法不会出现超时退出的情况
#2
更多评论
这样是可以的,但感觉不像是标准用法 ``` package main import ( "context" "fmt" "sync" "time" ) var wg sync.WaitGroup // main 设置一个 3s 超时的 ctx,传给每个 goroutine 第一个参数,每个 goroutine 又发起协程处理任务, // 假设需要 5s,通过监听 ctx.Done 判断是否超时退出 func main() { ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() wg.Add(2) go watch(ctx, 1) go watch(ctx, 2) wg.Wait() fmt.Println("finished") } func watch(ctx context.Context, flag int) { defer wg.Done() go func() { fmt.Printf("doing something flag:%d\n", flag) time.Sleep(50 * time.Second) fmt.Println("finished flag:", flag) }() select { case <-ctx.Done(): fmt.Printf("watch %d %s\n", flag, ctx.Err()) return } } ```
#1