我有 16 个返回输出的 go 例程,通常是一个结构。
struct output{
index int,
description string,
}
现在所有这 16 个 go routines 并行运行,所有 go routines 的预期输出结构总数预计为一百万。我已经使用了 go lang 的基本排序,这样做非常昂贵,有人可以帮助我采用基于索引对输出进行排序的方法,我需要将“描述”字段写入基于文件按索引排序。
例如, 如果 go 例程给出的输出为 {2, "Hello"},{9,"Hey"},{4,"Hola"},我的输出文件应该包含 你好 你好 嘿
所有这些 go 例程并行运行,我无法控制执行顺序,因此我传递索引以最终对输出进行排序。
最佳答案
在进入答案之前要考虑的一件事是您的示例代码将无法编译。要在 Go 中定义一种结构类型,您需要将语法更改为
type output struct {
index int
description string
}
就您的问题的潜在解决方案而言 - 如果您已经可靠地拥有唯一索引以及结果集的预期数量 - 您根本不需要进行任何排序。而是通过 channel 同步 go 例程,并将输出插入到相应索引处的已分配 slice 中。然后您可以迭代该 slice 以将内容写入文件。例如:
ch := make(chan output) //each go routine will write to this channel
wg := new(sync.WaitGroup) //wait group to sync all go routines
//execute 16 goroutines
for i := 0; i < 16; i++ {
wg.Add(1)
go worker(ch, wg) //this is expecting each worker func to call wg.Done() when completing its portion of work
}
//create a "quit" channel that will be used to signal to the select statement below that your go routines are all done
quit := make(chan bool)
go func() {
wg.Wait()
quit <- true
}()
//initialize a slice with length and capacity to 1mil, the expected result size mentioned in your question
sorted := make([]string, 1000000, 1000000)
//use the for loop, select pattern to sync the results from your 16 go routines and insert them into the sorted slice
for {
select {
case output := <-ch:
//this is not robust - check notes below example
sorted[output.index] = output.description
case <-quit:
//implement a function you could pass the sorted slice to that will write the results
// Ex: writeToFile(sorted)
return
}
}
关于此解决方案的几点注意事项:它取决于您是否了解预期结果集的大小。如果您不知道结果集的大小 - 在 select 语句中,您将需要检查从 ch
读取的索引是否超过了 sorted
的长度在插入之前 slice 并分配额外的空间我们的程序将因越界错误而崩溃
关于go例程的golang顺序输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44475474/