【问题标题】:Why does this goroutine block?为什么这个 goroutine 会阻塞?
【发布时间】:2017-07-14 22:41:36
【问题描述】:

这个 goroutine 阻塞...

go log.Fatal(http.ListenAndServe(":8000", nil))
log.Print("This doesn't print")

这个 goroutine 不会阻塞...

go func() {
    log.Fatal(http.ListenAndServe(":8000", nil))
}()
log.Print("This prints")

这个 goroutine 也不会阻塞...

go http.ListenAndServe(":8000", nil)
log.Print("This prints")

【问题讨论】:

    标签: go goroutine


    【解决方案1】:

    这是根据规范:

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

    https://golang.org/ref/spec#Go_statements

    go log.Fatal(http.ListenAndServe(":8000", nil))
    

    第一个参数是

    http.ListenAndServe(":8000", nil)
    

    在执行函数log.Fatal作为goroutine之前会被评估,从而阻塞。

    【讨论】:

      【解决方案2】:

      go log.Fatal(http.ListenAndServe(":8000", nil)) 等价于

      e := http.ListenAndServe(":8000", nil)
      go log.Fatal(e)
      

      当然会阻塞。至于
      go func() { log.Fatal(http.ListenAndServe(":8000", nil)) }()

      它作为一个独立的 goroutine 开始执行函数。然后你调用log.Print("This prints"),因为一个记录器可以同时从多个goroutines中使用,所以它会打印出来。

      【讨论】:

        【解决方案3】:

        嗯, 我跑了程序:

        package main
        
        import (
            "net/http"
            "log"
        )
        
        func main() {
            go log.Fatal(http.ListenAndServe(":8000", nil))
            log.Print("This doesn't print")
        }
        

        而且它似乎运作良好:

        curl 127.0.0.1:8000 -v
        * Rebuilt URL to: 127.0.0.1:8000/
        *   Trying 127.0.0.1...
        * TCP_NODELAY set
        * Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
        > GET / HTTP/1.1
        > Host: 127.0.0.1:8000
        > User-Agent: curl/7.51.0
        > Accept: */*
        > 
        < HTTP/1.1 404 Not Found
        < Content-Type: text/plain; charset=utf-8
        < X-Content-Type-Options: nosniff
        < Date: Fri, 24 Feb 2017 08:22:19 GMT
        < Content-Length: 19
        < 
        404 page not found
        * Curl_http_done: called premature == 0
        * Connection #0 to host 127.0.0.1 left intact
        

        我的 go 版本:

        go1.7.3 darwin/amd64
        

        请指定有关您的运行时的更多信息,例如 go 版本、架构等。

        【讨论】:

          猜你喜欢
          • 2021-12-09
          • 1970-01-01
          • 1970-01-01
          • 2011-10-16
          • 1970-01-01
          • 1970-01-01
          • 2011-10-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多