《Go语言程序设计》这本书中的示例服务器2有问题吗?

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

The Go Programming Language book example server2 is wrong?

问题

我正在阅读《Go语言圣经》这本书。在第1章的第2个服务器示例中,使用了互斥锁来防止竞态条件。然而,我复制了代码并尝试运行它,结果得到了不一致的结果。示例中的代码有问题吗?

以下是我使用的代码:

server.go

  1. package server
  2. import (
  3. "fmt"
  4. "log"
  5. "net/http"
  6. "sync"
  7. )
  8. const (
  9. PORT string = ":8000"
  10. )
  11. var count int
  12. var mu sync.Mutex
  13. func Run() {
  14. http.HandleFunc("/", handler)
  15. http.HandleFunc("/count", counter)
  16. fmt.Printf("Server is listening on port: %s\n", PORT)
  17. log.Fatal(http.ListenAndServe(PORT, nil))
  18. }
  19. func handler(w http.ResponseWriter, r *http.Request) {
  20. mu.Lock()
  21. count++
  22. mu.Unlock()
  23. fmt.Fprintf(w, "URL Path = %q\n", r.URL.Path)
  24. }
  25. func counter(w http.ResponseWriter, r *http.Request) {
  26. mu.Lock()
  27. fmt.Fprintf(w, "Count = %d\n", count)
  28. mu.Unlock()
  29. }

main.go

  1. package main
  2. import "book/server"
  3. func main() {
  4. server.Run()
  5. }

当我运行go run main.go并访问两个页面localhost:8000localhost:8000/count时:

  1. 每当我刷新/count页面时,计数会增加。为什么?
  2. 每当我刷新//count页面时,显示的计数增加是不一致的?不符合刷新次数。为什么?

我原本期望只有在访问/页面时计数才会增加,而不是在访问/count页面时增加,并且计数会根据我刷新的次数增加。

英文:

I am going through The Go programming Language Book. In chapter 1, server 2 example: Book's code the mutex is used to prevent the race condition. However i copied the code and tried to run it and it's giving inconsistent result. Is the code in the example wrong?

Here's how i used the code:

server.go

  1. package server
  2. import (
  3. "fmt"
  4. "log"
  5. "net/http"
  6. "sync"
  7. )
  8. const (
  9. PORT string = ":8000"
  10. )
  11. var count int
  12. var mu sync.Mutex
  13. func Run() {
  14. http.HandleFunc("/", handler)
  15. http.HandleFunc("/count", counter)
  16. fmt.Printf("Server is listening on port: %s\n", PORT)
  17. log.Fatal(http.ListenAndServe(PORT, nil))
  18. }
  19. func handler(w http.ResponseWriter, r *http.Request) {
  20. mu.Lock()
  21. count++
  22. mu.Unlock()
  23. fmt.Fprintf(w, "URL Path = %q\n", r.URL.Path)
  24. }
  25. func counter(w http.ResponseWriter, r *http.Request) {
  26. mu.Lock()
  27. fmt.Fprintf(w, "Count = %d\n", count)
  28. mu.Unlock()
  29. }

main.go

  1. package main
  2. import "book/server"
  3. func main() {
  4. server.Run()
  5. }

When i run: go run main.go and visit the two pages localhost:8000 and localhost:8000/count

  1. Whenever I refresh the /count page the count increases. Why?
  2. Whenever I refresh the / and /count page the count shown are inconsistently increased? Not according to the number of refreshes. Why?

I was expecting the count would only increase when i visit / page and not /count page and it would increase according to the number of refreshes I did.

答案1

得分: 6

这是因为当你用浏览器测试网页时,大部分情况下,浏览器也会发送一个请求到 http://localhost:8000/favicon.ico。请参考下面的截图:

《Go语言程序设计》这本书中的示例服务器2有问题吗?

没有专门处理 /favicon.ico 的处理程序,它与 / 匹配,所以会由 server.handler 处理。

建议使用其他工具来测试这种类型的演示。例如,使用 curl 命令:

  1. $ curl 'http://localhost:8000/'
  2. $ curl 'http://localhost:8000/count'
英文:

That's because when you test the web page with a browser, most of the time, the browser will send a request to http://localhost:8000/favicon.ico too. See the screenshot below:

《Go语言程序设计》这本书中的示例服务器2有问题吗?

There is not a dedicated handler for /favicon.ico, and it matches /, so it will be handled by server.handler.

It's recommended to use other tools for testing such kind of demos. For example, curl:

  1. $ curl 'http://localhost:8000/'
  2. $ curl 'http://localhost:8000/count'

huangapple
  • 本文由 发表于 2023年5月12日 11:38:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76232959.html
匿名

发表评论

匿名网友

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

确定