context.WithDeadline在传递上下文时去常规吗?
我已经整理了一些示例代码,这些代码将为切片中的每个项目启动一个新的goroutine。 此时,这将等待完成通道被称为len(切片)次。
但是,我还想在goroutines中实现事件泄漏的超时。 似乎context.WithDeadline(或者可能是WithTimeout?)是要使用的适当函数。
例如,假设我想为从main()初始化的所有goroutine传递23秒的截止日期。 但是,我不清楚我应该怎么做。
我和Go Concurrency Patterns: Context (on the go blog)一起读过godoc,但作为一个新的地鼠, 我不是更聪明的人。我发现的许多例子都使用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!")
}
答案 0 :(得分:3)
您需要做的就是将上下文放入要使用它的函数中。在很多情况下,您可以使用简单的闭包,或者在这种情况下,将其添加到函数参数中。
准备好上下文后,您可以在Context.Done()
频道上进行选择,以确定其过期时间。
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
而不是依靠通过频道计算令牌,并使用延迟来调用完成。