golang多个routine操作map或者slice需要上锁

妖精的绣舞 提交于 2019-12-04 23:58:16

最近写服务器代码,运行期间突然panic,最后找到原因是因为map不是线程安全的,那这就简单啦,来一把读写锁。以下附上代码:

type QueryExchangerFlowBySomeTime struct {
    com.HandlerDemo
}
func (self *QueryExchangerFlowBySomeTime) FuckBody(body interface{}) (result interface{}, err error) {
    obj := *body.(*map[string]interface{})
    ip:=to.String(obj["ip"])
    granule:=to.Int64(obj["granule"])
    log.Println("传入:",granule)
    retMap:=make(map[string]interface{})
    retMap["starttime"]=GetHisTime()
    ips:=GetAllMac(ip)
    retData:=ReqDataHub{}
    time_out:=make(chan int,2)
    go ReqTimeOut(time_out,1,DATAHUB_REQ_TIME)
    var wg sync.WaitGroup
    for _,v:=range ips{
        wg.Add(1)
        go func(v string,g int64,ipt string){
            retData.Lock()
            retData.Data[v]=GetDataHubDataByIp(v,g,ipt)
            retData.Unlock()
            wg.Done()
        }(v,granule,ip)
    }
    select{
    case <-time_out:
        return com.Result{
            Status:"209",
            Msg:"请求超时",
        },nil
    default:
        wg.Wait()

}
    retMap["data"]=retData
    return com.Result{
        Status:"200",
        Data:retMap,
        Msg:"成功",
    },nil
}
func (self *QueryExchangerFlowBySomeTime) CheckBody(body interface{}) error {
    obj := *body.(*map[string]interface{})
    if err := com.HasValues(obj,"granule","ip"); err != nil {
        return err
    }
    return nil
}


golang的锁是不可重入的锁,就是说成双成对的出现,其实关键的部分就在操作map的前后加上锁,, retData.Lock() 和redData.Unlock(),FuckBody是封装的一套业务处理函数

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!