【问题标题】:sync.Mutex or http.HandleFunc not workingsync.Mutex 或 http.HandleFunc 不起作用
【发布时间】:2021-10-22 10:32:26
【问题描述】:

我正在使用教科书:“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()
}

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

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

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 端点返回一个小于 1000 的数字。请告诉我我做错了什么,或者我是否误解了 sync.Mutex 或 http.HandleFunc() 的工作原理。

【问题讨论】:

  • 谢谢,我尝试使用sync.WaitGroup,一切正常。
  • @mkopriva 请创建一个答案,以便我接受

标签: go webserver mutex goroutine


【解决方案1】:

互斥锁只确保没有两个 goroutine 将同时写入/读取count然而它不控制这些 goroutine 的执行顺序。

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

如果您只想所有go call() 完成后执行http.Get(".../count"),那么您可以使用sync.WaitGroup 来执行此操作。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2018-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多