2017-05-09 2 views
2

httprouterが2つのポートでlistenするhttpサーバをセットアップするには、88888080のようにしてください。それは両方の理由80808888。だからの上で細かく作品なぜこのgeroutineはこのhttpサーバのmain funcをブロックしますか?

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

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

しかし、それが正常に動作しない、私のサーバーは、私はいくつかの変更を行う8080 .IFに聞きますか?それは約closureまたは何か他のですか? Go language spec, "Go statements" -

答えて

6

関数値とパラメータは、呼び出し元のゴルーチン

にいつものように評価されています。

あなたはlog.Fatalへの呼び出しのためのゴルーチンを作成しているが、log.Fatalから引数はメインゴルーチンで、事前に評価されます。 Fatalの引数は戻り値http.ListenAndServeです。したがって、新しいゴルーチンはの後に始まり、ListenAndServeが返されます。

1

これを試してください。

最初のhttp.ListenAndServeステートメントは、関数内に配置する必要があります。これは、goroutineとして文のブロックを実行する方法の例の1つで、関数内にラップして呼び出します。

2番目のままにしておくと、ブロックする必要があります。

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)) 
} 
関連する問題