Go 映射并发使用
我遇到了这段代码,想知道这是否需要一个R/W互斥Go 映射并发使用,go,go-map,Go,Go Map,我遇到了这段代码,想知道这是否需要一个R/W互斥 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 com
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()
}
当每个go例程都有自己的map副本时,互斥锁是否有帮助?我们是否可以避免它以减少延迟?您需要保护map不被并发访问。代码是错误的,因为您正在读取并锁定互斥锁,但正在写入映射
for _, item := range vcnResponse.Items {
logger.Debug("Vcn object: %s", *item.DisplayName)
// maps are not concurrency safe
rwm.Lock()
vcnRegionMap[region] = append(vcnRegionMap[region], item)
rwm.Unlock()
}
请注意,此版本不使用
延迟
。延迟操作在函数返回时运行,而不是在块结束时运行。每次迭代读取一次锁定互斥锁n
,然后在函数返回时释放所有互斥锁。我没有看到复制vcnRegionMap
映射的任何地方。必须始终同步对任何值的并发修改。映射头的副本传递给函数,而不是映射的深度副本。每个goroutine仍在修改相同的基础映射。Go中的映射与切片一样,都是有效的引用类型。@f-z-N:如果是为了您自己的理解,那么投票就无关紧要了。它很可能最终被否决,因为如此频繁地重复关于这个主题的答案对整个网站没有多大用处。@f-z-N,你可以用任何一种方法。我个人会删除这些参数以消除混淆,因为四个参数中有三个是有效关闭的。您必须确保仍然复制regionName
,这是我用regionName:=regionName
惯用语所做的。@JimB,这真的可以吗?这仍然是对地图的书写。你不会破坏地图,但如果没有锁,它会很活泼。是的,你是对的,从技术上讲,这是一个写操作,即使密钥是相同的。问题根本不是关于分片,但这也有一场比赛可能值得一提。