为了账号安全,请及时绑定邮箱和手机立即绑定

http.TimeoutHandler 不会杀死相应的 ServeHTTP goroutine

http.TimeoutHandler 不会杀死相应的 ServeHTTP goroutine

Go
犯罪嫌疑人X 2023-06-26 17:39:20
超时处理程序将 ServeHTTP 执行转移到新的 goroutine 上,但在计时器结束后无法终止该 goroutine。对于每个请求,它都会创建两个 goroutine,但 ServeHTTP goroutine 永远不会用上下文杀死。无法找到杀死 goroutine 的方法。使用 time.Sleep 函数编辑For-loop,代表着巨大的计算量,超出了我们的计时器范围。可以用任何其他功能替换它。package mainimport (    "fmt"    "io"    "net/http"    "runtime"    "time")type api struct{}func (a api) ServeHTTP(w http.ResponseWriter, req *http.Request) {    // For-loop block represents huge computation and usually takes more time    // Can replace with any code    i := 0    for {        if i == 500 {            break        }        fmt.Printf("#goroutines: %d\n", runtime.NumGoroutine())        time.Sleep(1 * time.Second)        i++    }    _, _ = io.WriteString(w, "Hello World!")}func main() {    var a api    s := http.NewServeMux()    s.Handle("/", a)    h := http.TimeoutHandler(s, 1*time.Second, `Timeout`)    fmt.Printf("#goroutines: %d\n", runtime.NumGoroutine())    _ = http.ListenAndServe(":8080", h)}ServeHTTP goroutine 应该与请求上下文一起终止,通常不会发生这种情况。
查看完整描述

2 回答

?
翻过高山走不出你

TA贡献1875条经验 获得超3个赞

使用context.Context指示 go 例程中止其功能。当然,Go 例程必须侦听此类取消事件。

因此,对于您的代码,请执行以下操作:

ctx := req.Context() // this will be implicitly canceled by your TimeoutHandler after 1s


i := 0

for {

    if i == 500 {

        break

    }


    // for any long wait (1s etc.) always check the state of your context

    select {

    case <-time.After(1 * time.Second): // no cancelation, so keep going

    case <-ctx.Done():

        fmt.Println("request context has been canceled:", ctx.Err())

        return // terminates go-routine

    }

    i++

}


注意: Context被设计为链式的 - 允许以级联方式取消多个级别的子任务。

在典型的 REST 调用中,我们会发起数据库请求。因此,为了确保此类阻塞和/或缓慢的调用及时完成,不应使用Query ,而应使用QueryContext - 将 http 请求的上下文作为第一个参数传递。


查看完整回答
反对 回复 2023-06-26
?
幕布斯7119047

TA贡献1794条经验 获得超8个赞

我发现,如果你没有任何方法到达你的频道,那么当 goroutine 运行时就没有办法杀死或停止它。

在大型计算任务中,您必须在特定时间间隔或特定任务完成后观看通道。


查看完整回答
反对 回复 2023-06-26
  • 2 回答
  • 0 关注
  • 145 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信