美文网首页
Go race 数据竞争检测

Go race 数据竞争检测

作者: 水滴穿石 | 来源:发表于2020-03-16 10:42 被阅读0次

WEB服务

启动一个WEB服务,Add添加、Find列表,Del删除
go run main.go 服务可以正常运行,添加,列表,查看也都是正常的
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
上面代码测试看起貌似是正常的,如果访问量大的时候会发现在,列表条数小于添加数
image.png
100请求成功,go未报错
image.png
查看列表,97条记录,请求都成功了,go后台没有报错,为什么少了3条?(每次条数可能不一样)
http://127.0.0.1:1234/goods/find
image.png

go 启动增加参数 race,检测数据竞争

go run -race main.go
在重新执行一下上面的测试
image.png
  • 执行


    image.png

解决思路

1.加锁,全局变局多个协程添加修改时,为全局变量加锁
2.channel,如果不需要实时写入,可以先写入channel,异步更新
3....
加锁,请求1000次
image.png
查看结果,go未报错,列表添加1000个成功
image.png

相关文章

网友评论

      本文标题:Go race 数据竞争检测

      本文链接:https://www.haomeiwen.com/subject/oipwehtx.html