我正在阅读《go 编程语言书籍》。在第 1 章,服务器 2 示例中:书籍代码中,互斥体用于防止竞争条件。但是,我复制了代码并尝试运行它,但结果不一致。示例中的代码是否错误?
这是我使用代码的方式:
server.go
package server
import (
"fmt"
"log"
"net/http"
"sync"
)
const (
port string = ":8000"
)
var count int
var mu sync.mutex
func run() {
http.handlefunc("/", handler)
http.handlefunc("/count", counter)
fmt.printf("server is listening on port: %sn", port)
log.fatal(http.listenandserve(port, nil))
}
func handler(w http.responsewriter, r *http.request) {
mu.lock()
count++
mu.unlock()
fmt.fprintf(w, "url path = %qn", r.url.path)
}
func counter(w http.responsewriter, r *http.request) {
mu.lock()
fmt.fprintf(w, "count = %dn", count)
mu.unlock()
}
main.go
package main
import "book/server"
func main() {
server.Run()
}
当我运行时: go run main.go 并访问两个页面 localhost:8000 和 localhost:8000/count
- 每当我刷新 /count 页面时,计数就会增加。为什么?
- 每当我刷新 / 和 /count 页面时,显示的计数都会不一致地增加?不是按照刷新次数。为什么?
我预计计数只会在我访问 / 页面而不是 /count 页面时增加,并且会根据我刷新的次数而增加。
正确答案
那是因为当你用浏览器测试网页时,大多数时候,浏览器也会向http://localhost:8000/favicon.ico
发送请求。请参阅下面的屏幕截图:
/favicon.ico
没有专用的处理程序,它与 /
匹配,因此将由 server.handler
处理。
建议使用其他工具来测试此类演示。例如,curl
:
$ curl 'http://localhost:8000/'
$ curl 'http://localhost:8000/count'