英文:
Why does this goroutine block?
问题
这个 goroutine 阻塞...
go log.Fatal(http.ListenAndServe(":8000", nil))
log.Print("这不会打印")
这个 goroutine 不阻塞...
go func() {
log.Fatal(http.ListenAndServe(":8000", nil))
}()
log.Print("这会打印")
这个 goroutine 也不阻塞...
go http.ListenAndServe(":8000", nil)
log.Print("这会打印")
英文:
This goroutine blocks...
go log.Fatal(http.ListenAndServe(":8000", nil))
log.Print("This doesn't print")
This goroutine doesn't block...
go func() {
log.Fatal(http.ListenAndServe(":8000", nil))
}()
log.Print("This prints")
This goroutine also doesn't block...
go http.ListenAndServe(":8000", nil)
log.Print("This prints")
答案1
得分: 5
根据规范,这是这样的:
> 函数值和参数在调用的 goroutine 中按照通常的方式进行评估。
https://golang.org/ref/spec#Go_statements
在以下代码中:
go log.Fatal(http.ListenAndServe(":8000", nil))
第一个参数是
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
go log.Fatal(http.ListenAndServe(":8000", nil))
The first parameter is
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))
等同于
e := http.ListenAndServe(":8000", nil)
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
e := http.ListenAndServe(":8000", nil)
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
嗯,
我运行了这个程序:
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版本、架构等。
英文:
Hmm,
I ran program:
package main
import (
"net/http"
"log"
)
func main() {
go log.Fatal(http.ListenAndServe(":8000", nil))
log.Print("This doesn't print")
}
And it seems to work well:
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
My go version:
go1.7.3 darwin/amd64
Please specify more information about your runtime, like go version, architecture etc.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论