亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

何時將sync.Mutex與net/http和gorilla/mux一起使用

何時將sync.Mutex與net/http和gorilla/mux一起使用

Go
DIEA 2023-07-31 17:35:57
據我所知, net/http 包使用 goroutine 作為處理程序。我是否有必要鎖定地圖,sync.Mutex以防止nextId函數中可能出現錯誤,因為該函數可能會計算地圖的舊狀態?這是我的示例代碼:package mainimport (    "net/http"    "github.com/gorilla/mux"    "io/ioutil"    "fmt")var testData = map[int]string {    1: "foo",    2: "bar",}func main() {    r := mux.NewRouter()    r.HandleFunc("/data", getData).Methods("GET")    r.HandleFunc("/data", addData).Methods("POST")    http.ListenAndServe(":3000", r)}func getData(writer http.ResponseWriter, request *http.Request) {    for k, v := range testData {        fmt.Fprintf(writer, "Key: %d\tValue: %v\n", k, v)    }}func addData(writer http.ResponseWriter, request *http.Request) {    if data, err := ioutil.ReadAll(request.Body); err == nil {        if len(data) == 0 {            writer.WriteHeader(http.StatusBadRequest)            return        }        id := nextId()        testData[id] = string(data)        url := request.URL.String()        writer.Header().Set("Location", fmt.Sprintf("%s", url))        writer.WriteHeader(http.StatusCreated)    } else {        writer.WriteHeader(http.StatusBadRequest)    }}func nextId() int {    id := 1    for k, _ := range testData {        if k >= id {            id = k + 1;        }    }    return id}
查看完整描述

1 回答

?
墨色風雨

TA貢獻1853條經驗 獲得超6個贊

由于標準庫的 HTTP 服務器在其自己的 goroutine 上調用處理程序,因此您必須同步訪問處理程序外部定義的所有變量(其中訪問之一是寫入)。每當您使用 stdlib 的 HTTP 服務器時都必須執行此操作。使用標準庫的多路復用器還是 Gorilla 的多路復用器并不重要。Goroutine 啟動發生在多路復用器外部(在調用多路復用器之前)。


如果不這樣做(如您的示例中所示),則會發生數據爭用,您可以通過使用以下選項運行它來驗證-race:


WARNING: DATA RACE

Write at 0x00c000090c30 by goroutine 21:

  runtime.mapassign_fast64()

      /usr/local/go/src/runtime/map_fast64.go:92 +0x0

  main.addData()

      /home/icza/gows/src/play/play.go:47 +0x191

  net/http.HandlerFunc.ServeHTTP()

      /usr/local/go/src/net/http/server.go:2007 +0x51

  github.com/gorilla/mux.(*Router).ServeHTTP()

      /home/icza/gows/pkg/mod/github.com/gorilla/[email protected]/mux.go:212 +0x13e

  net/http.serverHandler.ServeHTTP()

      /usr/local/go/src/net/http/server.go:2802 +0xce

  net/http.(*conn).serve()

      /usr/local/go/src/net/http/server.go:1890 +0x837


Previous read at 0x00c000090c30 by goroutine 7:

  runtime.mapiternext()

      /usr/local/go/src/runtime/map.go:851 +0x0

  main.getData()

      /home/icza/gows/src/play/play.go:32 +0x194

  net/http.HandlerFunc.ServeHTTP()

      /usr/local/go/src/net/http/server.go:2007 +0x51

...


查看完整回答
反對 回復 2023-07-31
  • 1 回答
  • 0 關注
  • 203 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號