context.WithDeadline 同时传递上下文去例程?
我整理了一些示例代码,这些代码将为我的 slice 中的每个项目启动一个新的 goroutine。 目前,这将等待 done channel 被调用 len(slice) 次。
但是,我还想在 goroutines 中实现超时以防止事件泄漏。 context.WithDeadline(或者 WithTimeout?)似乎是合适的函数。
例如,假设我想为所有从 main() 初始化的 goroutine 传递 23 秒的截止日期。 但是,我不清楚应该如何执行此操作。
我已经阅读了 godoc 和 Go Concurrency Patterns: Context (on the go blog)但作为一只新的地鼠, 我一点也不聪明。我发现的许多示例都使用了 http.handler(或类似示例,因此它们让我有些困惑。
在此处传递带有截止日期/超时的上下文的合适方法是什么。
package main
import (
"fmt"
"time"
)
func sleepNow(i int, done chan bool) {
time.Sleep(time.Duration(i) * time.Second)
fmt.Println(i, "has just woken up from sleep and the time is", time.Now())
done <- true
}
func main() {
done := make(chan bool)
numbersSlice := []int{10, 20, 30, 12}
for _, v := range(numbersSlice){
go sleepNow(v, done)
}
for x := 0; x < len(numbersSlice); x++ {
<-done
}
fmt.Println("Looks like we are all done here!")
}
最佳答案
您需要做的就是将上下文放入要使用它的函数中。在许多情况下,您可以使用简单的闭包,或者在这种情况下,将其添加到函数参数中。
设置好上下文后,您可以在 Context.Done()
channel 上进行选择以确定它何时过期。
https://play.golang.org/p/q-n_2mIW2X
func sleepNow(i int, ctx context.Context, wg *sync.WaitGroup) {
defer wg.Done()
select {
case <-time.After(time.Duration(i) * time.Second):
fmt.Println(i, "has just woken up from sleep and the time is", time.Now())
case <-ctx.Done():
fmt.Println(i, "has just been canceled")
}
}
func main() {
var wg sync.WaitGroup
numbersSlice := []int{1, 5, 4, 2}
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
for _, v := range numbersSlice {
wg.Add(1)
go sleepNow(v, ctx, &wg)
}
wg.Wait()
cancel()
fmt.Println("Looks like we are all done here!")
}
您还应该使用 sync.WaitGroup
而不是依赖 channel 上的 token 计数,并使用 defer 来调用 Done。
关于go - context.WithDeadline 同时传递上下文去例程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43002046/