英文:
Erratic behavior in Windows?
问题
更新:问题标题可能会误导。这完全不是Go的错。
请参阅第一个评论或接受的答案。
以下代码(几乎相同)在Linux下正确计算页面浏览量,但在Windows下计算两次。
有人能找出原因吗?
package main
import (
"fmt"
"http"
)
func main() {
println("Running")
http.HandleFunc("/", makeHomeHandler())
http.ListenAndServe(":8080", nil)
}
// 这个版本在Linux版本的Golang下编译和运行都没问题
func makeHomeHandler() func(c *http.Conn, r *http.Request) {
views := 1
return func(c *http.Conn, r *http.Request) {
fmt.Fprintf(c, "Counting %s, %d so far.", r.URL.Path[1:], views)
views++
}
}
/*
// 这个版本在mingw版本的Golang下编译和运行都没问题
// 它使用了不同的处理函数参数类型,
// 但计数器显示“1 so far”,然后是“3 so far”,“5 so far”,依此类推。
func makeHomeHandler() func(c http.ResponseWriter, r *http.Request) {
views := 1
return func(c http.ResponseWriter, r *http.Request) {
fmt.Fprintf(c, "Counting %s, %d so far.", r.URL.Path[1:], views)
views++
}
}
*/
在Mingw下:
http://localhost:8080/monkeys => Counting monkeys, 1 so far.
http://localhost:8080/monkeys => Counting monkeys, 3 so far.
http://localhost:8080/donkeys => Counting donkeys, 5 so far.
这可能是一个bug吗?
后续:
实际上,如果我为另一个页面定义了一个额外的处理函数,比如:
http.HandleFunc("/test", testPageHandler)
它没有闭包,也没有增加任何东西,计数器仍然会增加,但只增加1:
所以,在Mingw下:
http://localhost:8080/monkeys => Counting monkeys, 1 so far.
http://localhost:8080/monkeys => Counting monkeys, 3 so far.
http://localhost:8080/test => 另一个不增加“views”的处理函数
http://localhost:8080/donkeys => Counting donkeys, 6 so far.
在Linux下的输出如预期:
http://localhost:8080/monkeys => Counting monkeys, 1 so far.
http://localhost:8080/monkeys => Counting monkeys, 2 so far.
http://localhost:8080/test => 另一个不增加“views”的处理函数
http://localhost:8080/donkeys => Counting donkeys, 3 so far.
<details>
<summary>英文:</summary>
Update: The question title can be misleading. This was not Go's fault at all.
See the first comment or the accepted answer.
This following code (well, almost the same) counts page views under Linux allright, but counts them double under Windows.
Can someone figure out why?
package main
import (
"fmt"
"http"
)
func main() {
println("Running")
http.HandleFunc("/", makeHomeHandler())
http.ListenAndServe(":8080", nil)
}
// this version compiles and run OK under the Linux version of Golang
func makeHomeHandler() func(c *http.Conn, r *http.Request) {
views := 1
return func(c *http.Conn, r *http.Request) {
fmt.Fprintf(c, "Counting %s, %d so far.", r.URL.Path[1:], views)
views++
}
}
/*
// this version compiles and run OK under the mingw version of Golang
// it uses a different argument type for the handler function,
// but the counter says "1 so far", then "3 so far", "5 so far", and so on.
func makeHomeHandler() func(c http.ResponseWriter, r *http.Request) {
views := 1
return func(c http.ResponseWriter, r *http.Request) {
fmt.Fprintf(c, "Counting %s, %d so far.", r.URL.Path[1:], views)
views++
}
}
*/
Under Mingw:
http://localhost:8080/monkeys => Counting monkeys, 1 so far.
http://localhost:8080/monkeys => Counting monkeys, 3 so far.
http://localhost:8080/donkeys => Counting donkeys, 5 so far.
Could this be a bug?
Followup:
In fact, if I define an additional handler for another page, like:
http.HandleFunc("/test", testPageHandler)
Wich does not have a closure, nor increments anything, the counter gets incremented anyway, but only +1:
So, still under Mingw:
http://localhost:8080/monkeys => Counting monkeys, 1 so far.
http://localhost:8080/monkeys => Counting monkeys, 3 so far.
http://localhost:8080/test => Another handler function that does not increment "views"
http://localhost:8080/donkeys => Counting donkeys, 6 so far.
Under Linux output is as spected:
http://localhost:8080/monkeys => Counting monkeys, 1 so far.
http://localhost:8080/monkeys => Counting monkeys, 2 so far.
http://localhost:8080/test => Another handler function that does not increment "views"
http://localhost:8080/donkeys => Counting donkeys, 3 so far.
</details>
# 答案1
**得分**: 5
我怀疑你所看到的行为是由于浏览器请求页面的favicon而不是由于Windows/mingw。如果你想知道,我正在使用6g和Darwin,我的Firefox 3.6也在运行Mac OS X。
为了加强我的怀疑,尝试在处理函数中添加以下内容:
fmt.Printf("Counting %s, %d so far.\n", r.URL.Path[1:], views)
然后你可以看到所有请求到达你的应用程序。一个来自刚启动的Firefox对URL http://localhost:8080/chuchichaestli 的请求会产生以下输出:
Counting chuchichaestli, 1 so far.
Counting favicon.ico, 2 so far.
因为Firefox还会请求你的go页面的favicon。
此外,尽管可能有多个并发请求,你没有对`views`进行锁定/同步访问。
<details>
<summary>英文:</summary>
I suspect that the behaviour you're seeing is due to the browser requesting a favicon for your page and not due to Windows/mingw. In case you wonder, I'm using 6g ond Darwin, my Firefox 3.6 is also running on Mac OS X.
To underline my suspicion, try adding the following to the handler function:
fmt.Printf("Counting %s, %d so far.\n", r.URL.Path[1:], views)
Then you can see all the requests reaching your application. One request from a freshly started Firefox to the URL http://localhost:8080/chuchichaestli yields this output:
Counting chuchichaestli, 1 so far.
Counting favicon.ico, 2 so far.
because Firefox also requests the favicon for your go page.
Furthermore you're not locking/synchronising access to `views` even though there could be multiple concurrent requests.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论