比较2张地图的元素 - 我这样做了吗?

时间:2013-02-11 10:57:39

标签: concurrency go

周末刚开始与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?

1 个答案:

答案 0 :(得分:2)

一些观察结果:

  • 您可能想要使用已删除的频道

    c := make(chan string, someNumber) // someNumber >= goroutines cca

  • 死锁源于一个没有人关闭的通道(这是范围语句终止的方式)。在Go中协调内容的机制因任务而异。在这种情况下,有些人可能会使用sync.WaitGroup。请仔细检查前面链接中的示例代码,以获取有关正确使用WaitGroup的提示。另一种选择是计算已启动的vs成品工人的一些/任何其他类型/方式(WaitGroup封装,但我倾向于将其视为过度杀伤)。

  • 在这种情况下,无需将指针传递给地图。 Go中的地图具有完整的引用语义(无论如何它只是引擎盖下的指针)。