在Windows中出现不稳定的行为?

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

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&#39;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 (
     &quot;fmt&quot;
        &quot;http&quot;
    )
    
    func main() {
        println(&quot;Running&quot;)
        http.HandleFunc(&quot;/&quot;, makeHomeHandler())
     http.ListenAndServe(&quot;:8080&quot;, 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, &quot;Counting %s, %d so far.&quot;, 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 &quot;1 so far&quot;, then &quot;3 so far&quot;, &quot;5 so far&quot;, 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, &quot;Counting %s, %d so far.&quot;, r.URL.Path[1:], views)
            views++
        }
    }
    */

Under Mingw:

    http://localhost:8080/monkeys =&gt; Counting monkeys, 1 so far.
    http://localhost:8080/monkeys =&gt; Counting monkeys, 3 so far.
    http://localhost:8080/donkeys =&gt; 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(&quot;/test&quot;, 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 =&gt; Counting monkeys, 1 so far.
    http://localhost:8080/monkeys =&gt; Counting monkeys, 3 so far.
    http://localhost:8080/test   =&gt; Another handler function that does not increment &quot;views&quot;
    http://localhost:8080/donkeys =&gt; Counting donkeys, 6 so far.



Under Linux output is as spected:

    http://localhost:8080/monkeys =&gt; Counting monkeys, 1 so far.
    http://localhost:8080/monkeys =&gt; Counting monkeys, 2 so far.
    http://localhost:8080/test   =&gt; Another handler function that does not increment &quot;views&quot;
    http://localhost:8080/donkeys =&gt; 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&#39;re seeing is due to the browser requesting a favicon for your page and not due to Windows/mingw. In case you wonder, I&#39;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(&quot;Counting %s, %d so far.\n&quot;, 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&#39;re not locking/synchronising access to `views` even though there could be multiple concurrent requests.

</details>



huangapple
  • 本文由 发表于 2010年10月13日 04:53:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/3918941.html
匿名

发表评论

匿名网友

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

确定