Go 语言使用WaitGroup个人笔记记录

本文记录了Go语言中WaitGroup的使用心得,详细解释了如何通过WaitGroup实现并发控制,确保goroutine间的同步,避免数据竞争问题。通过实例代码展示了WaitGroup的基本用法和在实际项目中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

func main() {
    //用于条数判断
    count := 0
    for nextTimeFlag {
        count++
        number, _ := strconv.Atoi(analysisReq.Number)
        if count > number+1 {
            nextTimeFlag = false
            continue
        }
        searchTimeArr = append(searchTimeArr, searchTime)
        //下一个周期时间用来判断是否是未来时,如果不是未来时间,那么将查询时间替换成下一个周期
        nextTime, flag := handleNextGranularityTime(searchTime, analysisReq.Granularity, analysisReq.Type)
        fmt.Println("下一粒度周期时间:", nextTime)
        searchTime = nextTime
        //b, _ := json.Marshal(dimensionArr)
        //fmt.Println("维度信息:", string(b))

        if !flag {
            //已经是未来时间了,不需要在转化下去
            nextTimeFlag = false
            continue
        }
    }

    var wg sync.WaitGroup
    //添加查询时间的长度
    wg.Add(len(searchTimeArr))
    //时间数据的数量,key为时间,value为对应时间查询的数量,用于后续比较计算转化 [通道]
    timeAnalysisDataLenMapChan := make(chan map[string]int, len(searchTimeArr))
    //时间多维度的map,key为时间,value为多维度map(key为多个维度的值,value默认0) [通道]
    timeDimessionsMapChan := make(chan map[string]map[string]int, len(searchTimeArr))
    nowTime := time.Now().UnixNano()
    for _, _searchTime := range searchTimeArr {
        go func(searchTime string) {
            _timeAnalysisDataLenMap := make(map[string]int)
            _timeDimessionsMap := make(map[string]map[string]int)
            _singleView, singleViewParams := GetSingleViewInfoByAnalysis(analysisReq, searchTime, dimensionArr)
            currentTime := time.Now().UnixNano()
            //根据单图从es中查询相关的数据
            data, _ := singleViewService.QuerySingleViewData(_singleView, *singleViewParams)
            fmt.Printf("根据单图信息查询数据 花费%d ms \n", (time.Now().UnixNano()-currentTime)/1000000)
            //b, _ = json.Marshal(data)
            //fmt.Println("数据", string(b))
            //多维度对应的map,key为多维度对应值的拼接,value默认0,主要用来判断是否已经存在此聚合维度的值
            var dimessionsMap map[string]int = nil
            //第一次查询,主要是为了返回第一个返回值多维度值的map
            resultDimessionsMap, _, _ := funnelService.getDataResult(data.Data, dimessionsMap, dimensionNameArr, 0)
            //根据当前周期查询的数量放入时间数据数量的chan通道
            _timeAnalysisDataLenMap[strings.Replace(searchTime, consts.SPLIT, consts.TIME_SPLIT, -1)] = len(data.Data)
            timeAnalysisDataLenMapChan <- _timeAnalysisDataLenMap
            //根据查询的多维度map放入时间多维度的map
            _timeDimessionsMap[strings.Replace(searchTime, consts.SPLIT, consts.TIME_SPLIT, -1)] = resultDimessionsMap
            timeDimessionsMapChan <- _timeDimessionsMap
            wg.Done()
        }(_searchTime)
    }
    //阻塞等待所有并发执行结束
    wg.Wait()
    //关闭通道,停止放入数据
    close(timeAnalysisDataLenMapChan)
    close(timeDimessionsMapChan)
    fmt.Printf("查询所有单图数据 花费%d ms \n", (time.Now().UnixNano()-nowTime)/1000000)

    //用两种形式跳出chan的循环,并将通道的值赋予timeAnalysisDataLenMap,timeDimessionsMap
    for {
        select {
        case _timeAnalysisDataLenMap, ok := <-timeAnalysisDataLenMapChan:
            if ok {
                for _searchTime, dataLen := range _timeAnalysisDataLenMap {
                    timeAnalysisDataLenMap[_searchTime] = dataLen
                }
            }else {
                goto _timeAnalysisDataLenMapEnd
            }
        }
    }
    _timeAnalysisDataLenMapEnd:
    _timeDimessionsMapEnd:
    for {
        select {
        case _timeDimessionsMap, ok := <-timeDimessionsMapChan:
            if ok {
                for _searchTime, dimenssionsMap := range _timeDimessionsMap {
                    timeDimessionsMap[_searchTime] = dimenssionsMap
                }
            }else {
                break _timeDimessionsMapEnd
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值