美文网首页
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