Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why goroutine block main func in this http server?

Tags:

go

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?

like image 927
LeoTao Avatar asked Dec 06 '22 14:12

LeoTao


1 Answers

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.

like image 157
hobbs Avatar answered Dec 16 '22 13:12

hobbs