Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在这种情况下,Go HTTP处理程序goroutine是否会立即退出?_Http_Go_Cancellation - Fatal编程技术网

在这种情况下,Go HTTP处理程序goroutine是否会立即退出?

在这种情况下,Go HTTP处理程序goroutine是否会立即退出?,http,go,cancellation,Http,Go,Cancellation,我有一个Go HTTP处理程序,如下所示: mux.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() if cn, ok := w.(http.CloseNotifier); ok { go func(done <-chan

我有一个Go HTTP处理程序,如下所示:

mux.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
    ctx, cancel := context.WithCancel(context.Background())

    defer cancel()

    if cn, ok := w.(http.CloseNotifier); ok {
        go func(done <-chan struct{}, closed <-chan bool) {
            select {
            case <-done:
            case <-closed:
                fmt.Println("client cancelled....................!!!!!!!!!")
                cancel()
            }
        }(ctx.Done(), cn.CloseNotify())
    }

    time.Sleep(5 * time.Second)

    fmt.Println("I am still running...........")

    fmt.Fprint(w, "cancellation testing......")
})
mux.HandleFunc(“/test”,func(w http.ResponseWriter,r*http.Request){
ctx,cancel:=context.WithCancel(context.Background())
推迟取消
如果cn,ok:=w.(http.CloseNotifier);ok{
围棋(完成您创建了一个可以取消的,当客户端关闭连接时您会取消它,但是您不会检查上下文,如果它被取消,您的处理程序也不会做任何不同的事情。上下文只携带超时和取消信号,它既没有能力也没有意图杀死/终止goroutines。goroutines t他自己必须监视这种取消信号并据此采取行动

因此,您看到的是代码的预期输出

您需要监视上下文,如果上下文被取消,则从处理程序返回“立即”

当然,如果你正在“睡觉”,你不能同时监视上下文。因此,请改用,如本例所示:

mux.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    if cn, ok := w.(http.CloseNotifier); ok {
        go func(done <-chan struct{}, closed <-chan bool) {
            select {
            case <-done:
            case <-closed:
                fmt.Println("client cancelled....................!!!!!!!!!")
                cancel()
            }
        }(ctx.Done(), cn.CloseNotify())
    }

    select {
    case <-time.After(5 * time.Second):
        fmt.Println("5 seconds elapsed, client didn't close")
    case <-ctx.Done():
        fmt.Println("Context closed, client closed connection?")
        return
    }

    fmt.Fprint(w, "cancellation testing......")
})
mux.HandleFunc(“/test”,func(w http.ResponseWriter,r*http.Request){
ctx,cancel:=context.WithCancel(context.Background())
推迟取消
如果cn,ok:=w.(http.CloseNotifier);ok{

围棋(完成了哦,我明白了,所以如果我在这里启动新的goroutine,也许这些goroutine也会启动新的goroutine,那么对于所有下游goroutine,我需要手动监控上下文?我想上下文包会帮助我立即终止这些goroutine!@lnshi上下文只包含超时和取消信息,它不会有权杀死/终止goroutines。goroutines本身必须监视这种取消信号并根据它采取行动。对不起,在监视了取消后,我发现我仍然不知道应该如何终止处理程序,我在这里补充了我的一点想法:你能帮我指出正确的方法吗?基本上我想实现t当客户端关闭连接时,我的服务器立即终止处理程序,释放资源,不做任何剩余的工作,然后无条件退出。@lnshi如果检测到取消,您必须从处理程序返回。这表示服务该请求的web服务器已结束。根据处理程序的操作,它必须监视(至少偶尔)取消的通道,它必须终止并返回。这是您的任务,不会自动发生。因此,请使用将实际工作放在for select case分支上的方法,并发送一个一次性信号,通知它开始?只是感到紧张