并发http请求没有响应

ffe*_*fel 8 concurrency go

我正在玩Go,我遇到了一个我无法解决的问题.

以下代码是重现我的问题的最不可能的代码.原始代码的目标是将http请求委托给goroutines.每个goroutine做了一些沉重的图像计算,并应该响应.

package main

import (
    "fmt"
    "runtime"
    "net/http"
)

func main() {
    http.HandleFunc("/", handle)
    http.ListenAndServe(":8080", nil)
}

func handle(w http.ResponseWriter, r *http.Request) {

    // the idea is to be able to handle several requests
    // in parallel

    // the "go" is problematic
    go delegate(w)
}

func delegate(w http.ResponseWriter) {

    // do some heavy calculations first

    // present the result (in the original code, the image)
    fmt.Fprint(w, "hello")
}
Run Code Online (Sandbox Code Playgroud)

go delegate(w)没有响应的情况下,没有go它可以很好地解决.

谁能解释一下发生了什么?非常感谢!

Den*_*ret 5

ListenAndServe 已经启动goroutine来调用你的处理函数,所以你不应该自己动手.

这是包源中相关函数的代码:

1089    func ListenAndServe(addr string, handler Handler) error {
1090        server := &Server{Addr: addr, Handler: handler}
1091        return server.ListenAndServe()
1092    }


1010    func (srv *Server) ListenAndServe() error {
1011        addr := srv.Addr
1012        if addr == "" {
1013            addr = ":http"
1014        }
1015        l, e := net.Listen("tcp", addr)
1016        if e != nil {
1017            return e
1018        }
1019        return srv.Serve(l)
1020    }


1025    func (srv *Server) Serve(l net.Listener) error {
1026        defer l.Close()
1027        var tempDelay time.Duration // how long to sleep on accept failure
1028        for {

1057            go c.serve()
1058        }
1059        panic("not reached")
1060    }


579 // Serve a new connection.
580 func (c *conn) serve() {
581     defer func() {
582         err := recover()

669         handler.ServeHTTP(w, w.req)
Run Code Online (Sandbox Code Playgroud)

所以你的代码应该就是这样

func handle(w http.ResponseWriter, r *http.Request) {
    // the idea is to be able to handle several requests
    // in parallel
    // do some heavy calculations first

    // present the result (in the original code, the image)
    fmt.Fprint(w, "hello")
}
Run Code Online (Sandbox Code Playgroud)