为什么goroutine阻止这个http服务器的主要功能?

Leo*_*Tao 2 go

我想设置一个http服务器,httprouter监听两个端口8888,8080就像下面的代码一样.

package main

import (
    "fmt"
    "github.com/julienschmidt/httprouter"
    "log"
    "net/http"
)

func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
    fmt.Fprint(w, "Welcome!\n")
}

func main() {
    router := httprouter.New()
    router.GET("/", Index)

    fmt.Println("listen on 8080")
    // this is where blocked
    go log.Fatal(http.ListenAndServe(":8080", router))
    fmt.Println("listen on 8888")
    log.Fatal(http.ListenAndServe(":8888", router))
}
Run Code Online (Sandbox Code Playgroud)

但它无法正常工作,我的服务器只能听.8080如果我做了一些改动:

go func() { log.Fatal(http.ListenAndServe(":8080", router)) }()
Run Code Online (Sandbox Code Playgroud)

它既可以正常工作,8080也可以8888.为什么?它是关于closure还是别的什么?

hob*_*bbs 6

函数值和参数在调用goroutine中照常评估

- 去语言规范,"去声明".

您正在创建呼叫到的goroutine log.Fatal,但参数log.Fatal预先评估,在主够程.而且Fatal论证的是回归价值http.ListenAndServe.因此新的goroutine直到返回后才 开始ListenAndServe.


nov*_*ung 5

由于http.ListenAndServe()阻塞,并且在您的场景中,有两个,然后尝试将其中一个放在 goroutine 中。这个想法是将这两个 Web 服务器初始化语句的执行分开到单独的 goroutine 中。

func main() {
    router := httprouter.New()
    router.GET("/", Index)

    go func() {
        fmt.Println("listen on 8080")
        log.Fatal(http.ListenAndServe(":8080", router))
    }()

    fmt.Println("listen on 8888")
    log.Fatal(http.ListenAndServe(":8888", router))
}
Run Code Online (Sandbox Code Playgroud)