为什么这个 goroutine 会阻塞?

huangapple go评论123阅读模式
英文:

Why does this goroutine block?

问题

这个 goroutine 阻塞...

  1. go log.Fatal(http.ListenAndServe(":8000", nil))
  2. log.Print("这不会打印")

这个 goroutine 不阻塞...

  1. go func() {
  2. log.Fatal(http.ListenAndServe(":8000", nil))
  3. }()
  4. log.Print("这会打印")

这个 goroutine 也不阻塞...

  1. go http.ListenAndServe(":8000", nil)
  2. log.Print("这会打印")
英文:

This goroutine blocks...

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

This goroutine doesn't block...

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

This goroutine also doesn't block...

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

答案1

得分: 5

根据规范,这是这样的:

> 函数值和参数在调用的 goroutine 中按照通常的方式进行评估。

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

在以下代码中:

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

第一个参数是

  1. http.ListenAndServe(":8000", nil)

在执行 log.Fatal 函数作为 goroutine 之前,它将被评估,因此会阻塞。

英文:

This is according to the spec:

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

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

In

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

The first parameter is

  1. http.ListenAndServe(":8000", nil)

which will be evaluated before executing the function log.Fatal as a goroutine, thus blocking.

答案2

得分: 1

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

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

当然它会阻塞。至于

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

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

英文:

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

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

of course it blocks. As to
go func() {
log.Fatal(http.ListenAndServe(":8000", nil))
}()

it starts the execution of function as an independent goroutine. Then you call log.Print("This prints"), as a logger can be used simultaneously from multiple goroutines, so it prints.

答案3

得分: -2

嗯,
我运行了这个程序:

  1. package main
  2. import (
  3. "net/http"
  4. "log"
  5. )
  6. func main() {
  7. go log.Fatal(http.ListenAndServe(":8000", nil))
  8. log.Print("This doesn't print")
  9. }

看起来运行得很好:

  1. curl 127.0.0.1:8000 -v
  2. * Rebuilt URL to: 127.0.0.1:8000/
  3. * Trying 127.0.0.1...
  4. * TCP_NODELAY set
  5. * Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
  6. > GET / HTTP/1.1
  7. > Host: 127.0.0.1:8000
  8. > User-Agent: curl/7.51.0
  9. > Accept: */*
  10. >
  11. < HTTP/1.1 404 Not Found
  12. < Content-Type: text/plain; charset=utf-8
  13. < X-Content-Type-Options: nosniff
  14. < Date: Fri, 24 Feb 2017 08:22:19 GMT
  15. < Content-Length: 19
  16. <
  17. 404 page not found
  18. * Curl_http_done: called premature == 0
  19. * Connection #0 to host 127.0.0.1 left intact

我的go版本:

  1. go1.7.3 darwin/amd64

请提供关于您的运行环境的更多信息,比如go版本、架构等。

英文:

Hmm,
I ran program:

  1. package main
  2. import (
  3. &quot;net/http&quot;
  4. &quot;log&quot;
  5. )
  6. func main() {
  7. go log.Fatal(http.ListenAndServe(&quot;:8000&quot;, nil))
  8. log.Print(&quot;This doesn&#39;t print&quot;)
  9. }

And it seems to work well:

  1. curl 127.0.0.1:8000 -v
  2. * Rebuilt URL to: 127.0.0.1:8000/
  3. * Trying 127.0.0.1...
  4. * TCP_NODELAY set
  5. * Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
  6. &gt; GET / HTTP/1.1
  7. &gt; Host: 127.0.0.1:8000
  8. &gt; User-Agent: curl/7.51.0
  9. &gt; Accept: */*
  10. &gt;
  11. &lt; HTTP/1.1 404 Not Found
  12. &lt; Content-Type: text/plain; charset=utf-8
  13. &lt; X-Content-Type-Options: nosniff
  14. &lt; Date: Fri, 24 Feb 2017 08:22:19 GMT
  15. &lt; Content-Length: 19
  16. &lt;
  17. 404 page not found
  18. * Curl_http_done: called premature == 0
  19. * Connection #0 to host 127.0.0.1 left intact

My go version:

  1. go1.7.3 darwin/amd64

Please specify more information about your runtime, like go version, architecture etc.

huangapple
  • 本文由 发表于 2017年2月24日 15:19:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/42432880.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定