猿问

同步。互斥体或互斥体。句柄不工作

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


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


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”,它假设返回调用前一个端点的次数。


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 的数字。请告诉我我做错了什么,或者如果我对同步方式有误解。互斥体或互斥体。句柄()工作。


泛舟湖上清波郎朗
浏览 87回答 2
2回答

一只斗牛犬

互斥体仅确保没有两个戈鲁廷同时写入/读取,但它不控制这些戈鲁廷的执行顺序。count这意味着您的代码中没有任何内容可以确保在执行之前完成所有操作。go call()http.Get(".../count")如果只想在完成所有操作后执行,则可以使用同步来执行此操作。等待组。http.Get(".../count")go call()

子衿沉夜

sync.Mutex并且正在按预期工作,但每个处理程序都在自己的 go-例程中运行。不能保证任何调用都在调用之前运行,无论它们发布到服务器的顺序如何。http.HandleFunchandlercount在测试程序中,您可以删除前面的关键字,该关键字将确保所有请求都串联运行,因为等待服务器返回。或者,您可以使用注释中建议的方式,这将允许并行处理请求,但在发送计数请求之前等待它们全部完成。gocall()Get()WaitGroup
随时随地看视频慕课网APP

相关分类

Go
我要回答