周末刚开始与Go合作,我不确定我是否正确地使用了Go的特性,或者我是否完全没有使用过“Go-like”。
代码应该迭代在名为non_placed_alleles
的地图元素上,并将其中的每一个与placed_alleles
中的所有元素进行比较,这些元素也存储在地图中。我正在尝试对non_placed_alleles
中的每个元素使用一个go-routine,因为比较成本非常高并且需要永远。
这里有一点来自main函数:
runtime.GOMAXPROCS(8) // For 8 consecutive routines at once? got 10 CPUs
c := make(chan string)
for name, alleles := range non_placed_alleles {
go get_best_places(name, alleles, &placed_alleles, c)
// pointer to placed_alleles as we only read, not write - should be safe?
}
for channel_item := range c {
fmt.Println("This came back ", channel_item)
}
// This also crashes with "all goroutines are sleeping",
// but all results are printed
这是被调用的函数:
func get_best_places(name string, alleles []string, placed_alleles *map[string] []string, c chan string) {
var best_partner string
// Iterate over all elements of placed_alleles, find best "partner"
for other_key, other_value := range *placed_alleles {
best_partner := compare_magic() // omitted because boring
}
c <- best_partner
}
有没有办法让这个“更好”?快点?我是否正确使用了指针魔术和goroutines?
答案 0 :(得分:2)
一些观察结果:
您可能想要使用已删除的频道
c := make(chan string, someNumber) // someNumber >= goroutines cca
死锁源于一个没有人关闭的通道(这是范围语句终止的方式)。在Go中协调内容的机制因任务而异。在这种情况下,有些人可能会使用sync.WaitGroup。请仔细检查前面链接中的示例代码,以获取有关正确使用WaitGroup的提示。另一种选择是计算已启动的vs成品工人的一些/任何其他类型/方式(WaitGroup封装,但我倾向于将其视为过度杀伤)。
在这种情况下,无需将指针传递给地图。 Go中的地图具有完整的引用语义(无论如何它只是引擎盖下的指针)。