sync.Mutex 或 http.HandleFunc 不工作

sync.Mutex or http.HandleFunc not working

我正在使用教科书:“Go 编程语言”,其中展示了如何使用 Go 制作网络服务器。

按照他们给出的代码,我做了一个网络服务器:

package main

import (
    "fmt"
    "log"
    "net/http"
    "sync"
)

var mu sync.Mutex
var count int

func main() {
    http.HandleFunc("/", handler)
    http.HandleFunc("/count", counter)
    log.Fatal(http.ListenAndServe("localhost:8080", nil))
}

func handler(w http.ResponseWriter, r *http.Request) {
    mu.Lock()
    count++
    mu.Unlock()
    fmt.Fprintf(w, "URL.Path = %q\n", r.URL.Path)
}

func counter(w http.ResponseWriter, r *http.Request) {
    mu.Lock()
    fmt.Fprintf(w, "Count %d\n", count)
    mu.Unlock()
}

后来我想用 goroutines 测试我的知识,所以我制作了一个将调用服务器端点的程序:“/rest” 1000 次。

然后我调用端点:“/count”,假设 return 调用前一个端点的次数。

send.go

package main

import (
    "fmt"
    "net/http"
    "os"
    "strconv"
    "io/ioutil"
)

func main() {
    times, _ := strconv.Atoi(os.Args[1])
    
    for i := 0; i < times; i++ {
        go call()
    }

    response, err := http.Get("http://localhost:8080/count")
    if err != nil {
        fmt.Println("ERROR ", err)
    }
    
    text, _ := ioutil.ReadAll(response.Body)
    fmt.Println(string(text))
    response.Body.Close()
}

func call() {
    _, _= http.Get("http://localhost:8080/rest")
}

问题是这样的:/count 端点 return 是一个小于 1000 的数字。请告诉我我做错了什么,或者我是否误解了 sync.Mutex 或http.HandleFunc() 有效。

sync.Mutexhttp.HandleFunc 正常工作,但每个处理程序都是 运行 在它自己的 go-routine 中。无法保证 anyhandler 的调用是 运行 在对 count 的调用之前,无论它们发布到服务器的顺序如何。

在您的测试程序中,您可以删除 call() 之前的 go 关键字,这将确保所有请求都是 运行 串联的,因为 Get() 等待一个return 来自服务器。或者您可以按照评论中的建议使用 WaitGroup,这将允许并行处理请求,但在发送计数请求之前等待它们全部完成。

互斥量只保证没有两个goroutines同时write/readcount然而它不控制那些goroutines的顺序被执行。

这意味着您的代码中没有任何内容可以确保在执行 http.Get(".../count") 之前完成所有 go call()

如果你想在所有go call()完成后只执行http.Get(".../count"),那么你可以使用sync.WaitGroup.