【发布时间】:2020-10-05 16:00:25
【问题描述】:
我遇到了这段代码,想知道这是否需要一个 R/W Mutex。
method(){
var (
wg sync.WaitGroup
rwm sync.RWMutex
vcnRegionMap map[string][]core.Vcn
)
vcnRegionMap = make(map[string][]core.Vcn)
// This loops helps us in filtering unused regions
// for composition of region/vcnid ds
for _, regionName := range regions {
wg.Add(1)
go func(ctx context.Context, region string, vcnRegionMap map[string][]core.Vcn, wg *sync.WaitGroup, rwm *sync.RWMutex) {
// for locking maps
defer wg.Done()
// TODO: make this conditional if a region is specified
c.network.SetRegion(region)
vcnResponse, err := c.network.ListVcns(ctx, core.ListVcnsRequest{
CompartmentId: &c.cID,
})
if err != nil {
logger.Debug(err.Error())
}
if len(vcnResponse.Items) == 0 {
logger.Info("status 404: No Vcns found under the given OCID and region: %s", region)
return
}
logger.Info("status 200: Vcns found under the given OCID and region: %s", region)
for _, item := range vcnResponse.Items {
logger.Debug("Vcn object: %s", *item.DisplayName)
// maps are not concurrency safe
rwm.Lock()
defer rwm.Unlock()
vcnRegionMap[region] = append(vcnRegionMap[region], item)
}
}(ctx, regionName, vcnRegionMap, &wg, &rwm)
}
wg.Wait()
}
由于每个 goroutine 都有自己的 map 副本,Mutex 是否有帮助,我们可以避免它以减少延迟吗?
【问题讨论】:
-
我看不到任何地方正在复制
vcnRegionMap地图。您必须始终同步任何值的并发修改。 -
将地图头的副本传递给函数,而不是地图的深层副本。每个 goroutine 仍在修改相同的底层映射。
-
Go 中的地图和切片一样,实际上是引用类型。
-
@f-z-N:如果是为了您自己的理解,那么投票无关紧要。它最终可能会被否决,因为如此频繁地重复有关该主题的答案对整个网站来说并不是那么有用。
-
@f-z-N,无论哪种方式都可以。就我个人而言,我会删除参数以消除混淆,因为 4 个参数中有 3 个被有效地关闭了。但是,您必须确保仍然复制
regionName,我会使用regionName := regionName成语。