简体   繁体   中英

why goroutine block main func in this http server?

I want to setup a http server with httprouter listening on two ports 8888 and 8080 just like the code below.

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))
}

But it doesn't work properly,my server only listen on 8080 .If I make some change:

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

It works finely both on 8080 and 8888 .So why? It's about closure or something else?

The function value and parameters are evaluated as usual in the calling goroutine

Go language spec, "Go statements" .

You're creating a goroutine for the call to log.Fatal , but the arguments to log.Fatal are evaluated beforehand, in the main goroutine. And Fatal 's argument is the return value of http.ListenAndServe . So the new goroutine doesn't start until after ListenAndServe returns.

Since http.ListenAndServe() is blocking, and in your scenario, there are two of them, then try to put one of them in a goroutine. The idea is to separate the execution of those two web server initialization statements into separate 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))
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM