我有一个搜索功能,不需要对结果进行排序。它正在生成存储结果的表。我使用地图,因为它会自动删除相同的值。搜索功能需要大量的计算能力,我想并行执行它们。我当前的代码看起来像这样:
func assign(a int, b int, table *map[int]byte) {
(*table)[doSomething(a,b)] = 0
}
func incrementTable(table map[int]byte, paths []int) map[int]byte {
newTable := make(map[int]byte)
for p,_ := range table {
for _,m := range paths {
go assign(p, m, &newTable)
}
}
return newTable
}
但是,这会引发错误,因为它试图同时写入同一个映射。如何同时存储所有这些而不会使性能大幅下降?
如果我在没有
go
关键字的情况下运行代码,代码运行良好,所以我知道其他一切都有效。
即使您使用
sync.Map
,搜索函数,正如其所写,将返回一个正在同时填充的地图。这意味着,您的程序可能会查找不存在但稍后会添加的元素。
通常,完成所有搜索后您会想要查看地图。为此,您可以使用
WaitGroup
和通道来从搜索 goroutine 中读取结果:
result:=make(chan Result)
wg:=sync.WaitGroup()
resultMap:=make(map[string]int)
// Collect the results in a map
go func() {
for r:=range result {
resultMap[r]=0
}
}
for p,_ := range table {
for _,m := range paths {
wg.Add(1)
go doSearch(t table, p path) {
defer wg.Done()
result <- doSomething(t,p)
}(p,m)
}
}
wg.Wait()
close(result)
// Here, the resultMap has all the results.