当ctx超时时,如何完全终止正在运行的go func()?
当我需要ctx超时时,我应该怎么做才能完全终止正在执行longRunningCalculation()的方法当ctx超时时,如何完全终止正在运行的go func()?,go,Go,当我需要ctx超时时,我应该怎么做才能完全终止正在执行longRunningCalculation()的方法 主程序包 进口( “上下文” “日志” “时间” ) func longRunningCalculation(时间成本整数)chan字符串{ 结果:=生成(chan字符串) go func(){ time.Sleep(time.Second*(time.Duration(timeCost))) log.Println(“仍在做其他事情…”)/即使超时,此goroutine仍在执行其他任务
主程序包
进口(
“上下文”
“日志”
“时间”
)
func longRunningCalculation(时间成本整数)chan字符串{
结果:=生成(chan字符串)
go func(){
time.Sleep(time.Second*(time.Duration(timeCost)))
log.Println(“仍在做其他事情…”)/即使超时,此goroutine仍在执行其他任务。
结果要在调用方的上下文超时时停止由longRunningCalculation
启动的goroutine,需要将ctx
传递到longRunningCalculation
并显式处理上下文超时,方法与在jobWithTimeout
这样做也意味着不要调用time.Sleep
,而是选择time.Tick
,因此两个计时器同时运行。如下所示:
package main
import (
"context"
"log"
"time"
)
func longRunningCalculation(ctx context.Context, timeCost int) chan string {
result := make(chan string)
go func() {
calcDone := time.Tick(time.Second * time.Duration(timeCost))
log.Printf("entering select (longRunningCalculation)")
select {
case <-ctx.Done():
result <- "Caller timed out"
return
case <-calcDone:
log.Println("Still doing other things...") //Even if it times out, this goroutine is still doing other tasks.
result <- "Done"
}
log.Println(timeCost)
}()
return result
}
func jobWithTimeout() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
result := longRunningCalculation(ctx, 3)
log.Printf("entering select (jobWithTimeout)")
select {
case <-ctx.Done():
log.Println(ctx.Err())
return
case res := <-result:
log.Println(res)
}
}
func main() {
jobWithTimeout()
}
主程序包
进口(
“上下文”
“日志”
“时间”
)
func longRunningCalculation(ctx context.context,timeCost int)chan字符串{
结果:=生成(chan字符串)
go func(){
calcDone:=time.Tick(time.Second*time.Duration(timeCost))
log.Printf(“输入select(longRunningCalculation)”)
挑选{
如果您无法停止其他人的代码,您可以让代码(在适当的时候)询问“我现在应该停止吗?”来停止代码如果它得到一个答案,告诉它现在停止,它可以停止。如果它调用其他人的例行程序花费太长时间,你真的无能为力。这是真的,逻辑是复杂的。围棋没有魔力。如果你想让你的goroutine停止,你需要让它停止。这不仅仅是神奇地推断有一些相关的co在函数中使用上下文时,它应该始终是go标准中定义的第一个参数。为了能够中断longRunningCalculation
,您必须中断它所做的工作,并检查
package main
import (
"context"
"log"
"time"
)
func longRunningCalculation(ctx context.Context, timeCost int) chan string {
result := make(chan string)
go func() {
calcDone := time.Tick(time.Second * time.Duration(timeCost))
log.Printf("entering select (longRunningCalculation)")
select {
case <-ctx.Done():
result <- "Caller timed out"
return
case <-calcDone:
log.Println("Still doing other things...") //Even if it times out, this goroutine is still doing other tasks.
result <- "Done"
}
log.Println(timeCost)
}()
return result
}
func jobWithTimeout() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
result := longRunningCalculation(ctx, 3)
log.Printf("entering select (jobWithTimeout)")
select {
case <-ctx.Done():
log.Println(ctx.Err())
return
case res := <-result:
log.Println(res)
}
}
func main() {
jobWithTimeout()
}