Go race 數(shù)據(jù)競爭檢測

WEB服務(wù)

啟動一個WEB服務(wù),Add添加、Find列表,Del刪除
go run main.go 服務(wù)可以正常運行,添加,列表,查看也都是正常的
http://127.0.0.1:1234/goods/add
http://127.0.0.1:1234/goods/find
  • main.go
package main

import (
    "fmt"
    "net/http"
    _ "net/http/pprof" // 啟用pprof
    "os"
    "pf/goods"
)

var port string = "0.0.0.0:1234"

func main() {
    os.Setenv("name", "pprof")
    fmt.Println("listen", port)
    http.HandleFunc("/goods/add", goods.Add)
    http.HandleFunc("/goods/find", goods.Find)
    http.HandleFunc("/goods/del", goods.Del)
    err := http.ListenAndServe(port, nil)
    if err != nil {
        fmt.Println("http error:", err)
    }
}
  • goods.go
package goods

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

type GoodsModel struct {
    Id   int
    Name string
}

var Goods []*GoodsModel = make([]*GoodsModel, 0, 10)
var id int = 1

func Add(res http.ResponseWriter, req *http.Request) {
    g := GoodsModel{
        Id:   id,
        Name: os.Getenv("name") + "-" + strconv.Itoa(id),
    }
    Goods = append(Goods, &g)
    fmt.Println("add ok", id, &g)
    id++
    res.Write([]byte("add ok"))

}

func Find(res http.ResponseWriter, req *http.Request) {
    count := "count:" + strconv.Itoa(len(Goods)) + "\n"
    c := "cap:" + strconv.Itoa(cap(Goods)) + "\n"
    res.Write([]byte(count))
    res.Write([]byte(c))
    for k, g := range Goods {
        str := fmt.Sprintf("k:%d, id:%d, name:%s\n", k, g.Id, g.Name)
        res.Write([]byte(str))
    }
}

func Del(res http.ResponseWriter, req *http.Request) {
    Goods = make([]*GoodsModel, 0)
    id = 1
    res.Write([]byte("del ok"))
}
  • 增加
http://127.0.0.1:1234/goods/add
image.png
  • 列表
http://127.0.0.1:1234/goods/find
image.png
上面代碼測試看起貌似是正常的,如果訪問量大的時候會發(fā)現(xiàn)在,列表條數(shù)小于添加數(shù)
image.png
100請求成功,go未報錯
image.png
查看列表,97條記錄,請求都成功了,go后臺沒有報錯,為什么少了3條?(每次條數(shù)可能不一樣)
http://127.0.0.1:1234/goods/find
image.png

go 啟動增加參數(shù) race,檢測數(shù)據(jù)競爭

go run -race main.go
在重新執(zhí)行一下上面的測試
image.png
  • 執(zhí)行


    image.png

解決思路

1.加鎖,全局變局多個協(xié)程添加修改時,為全局變量加鎖
2.channel,如果不需要實時寫入,可以先寫入channel,異步更新
3....
加鎖,請求1000次
image.png
查看結(jié)果,go未報錯,列表添加1000個成功
image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容