我确实有同样的问题,并想出了以下方法:
https://play.golang.org/p/9F9T_sYIof
使用:context.WithTimeout(context.Background(), 10*time.Second)
:
https://play.golang.org/p/WK0ebe0c9t
我不知道这是否是正确的做法,但它有效:
package main
import (
"context"
"fmt"
"sync"
"time"
)
func doWork(element int, wg *sync.WaitGroup) {
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(10*time.Second))
defer cancel()
ch := make(chan struct{})
go func() {
time.Sleep(time.Second)
fmt.Printf("element = %+v\n", element)
ch <- struct{}{}
}()
select {
case <-ch:
case <-ctx.Done():
fmt.Println(ctx.Err())
}
wg.Done()
}
func main() {
var wg sync.WaitGroup
elements := []int{1, 2, 3}
for _, element := range elements {
wg.Add(1)
go doWork(element, &wg)
}
wg.Wait()
}
注意 doWork
函数中的 goroutine:
go func(ch chan struct{}) {
}(ch)
这是我不确定是否最佳实践的部分,但似乎是在使用上下文时处理 ctx.Done()
时要遵循的模式。
WithTimeout
本身调用WithDeadline
,请看内部实现:func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { return WithDeadline(parent, time.Now().Add(timeout)) }
- wasmup