1 回答

TA贡献2041条经验 获得超4个赞
有多种方法可以做到这一点。
一本“教科书”是这样的:
results := make(chan *score)
for i, config := range strategyConfigs {
state := newState(&config)
go a.runBenchmark(state, results)
}
for i := 0; i < len(strategyConfigs); i++ {
scores[i] = <-results
}
...,然后修改方法以不返回任何值,并接受类型的第二个参数。runBenchmark
chan *score
代码段是这样滚动的:
创建通道以交换类型为 的值。
*score
开始运行-我想-“一个代理人”的metod的戈鲁丁。
该方法通过提交给它的通道发送(指向)它计算的对象并退出。runBenchmark
score
另一个循环执行与生成的 goroutines 一样多的通道接收,并将每个接收的值放入生成的切片中。
警告:
这预先假定在多个戈鲁丁同时运行的情况下执行它是可以的。
a
runBenchmark
如果不能,你将需要创建一个单独的来运行每个单独的戈鲁廷。
鉴于你的例子不是太小,我很难对它有多难/多简单做出有根据的猜测。
如果您需要这方面的帮助,请单独提出一个狭隘的问题。a
如果你有,比如,数亿个“策略配置”,这种方法会过于简单,因为所有的goroutines都会一次生成,a)这是浪费资源;b)如果数字太大,甚至可能失败。
教科书上的解决方法是使用所谓的“扇出” - 当你有一个戈鲁廷通过一个通道接收“任务”并将它们分配到有限数量的工人大流子上时,这些工人戈鲁廷始终保持在一定限制以下。你可以从这里开始。
另一种方法是利用这样一个事实,即在Go中,数组的每个元素(和切片 - 通过扩展)都被视为一个单独的变量。这意味着从工作线程中同时更新生成的切片的各个元素是可以的 - 只要切片是预先分配的并且永远不会重新分配(使用,重新切片等操作),而此过程正在进行中。append
为了演示,让我们使用“等待组”:
import "sync"
var wg sync.WaitGroup
scores := make([]*score, len(strategyConfigs))
wg.Add(len(strategyConfigs))
for i, config := range strategyConfigs {
state := newState(&config)
go a.runBenchmark(state, &scores[i], &wg)
}
wg.Wait()
应将方法修改为具有runBenchmark
defer wg.Done()
作为其第一个语句,并接受两个附加参数 — 类型和 。*score
*sync.WaitGroup
在这里,开始在单独的 goroutine 中运行,并传递要更新其结果的元素的地址和等待组的地址以发出“任务完成”信号。runBenchmark
请注意,基本上与第一种情况下相同的警告适用。
如您所见,戈鲁廷确实不返回任何值。这主要是因为当它可能的时候,产生它的戈鲁廷可能早已消失,并且没有地方可以返回该值。
因此,基本上有两种方法可以“获取数据”:
在通道上发送该值(并从该通道接收其他一些戈鲁丁)。
这是Go的面包和黄油。我建议从这种方法开始,并使用它,直到你对它感到完全舒服。
更新内存中的某个位置,前提是没有其他 goroutine 执行相同的操作(否则您将遇到数据竞赛)。
在某些情况下,这种方法可能更快(甚至更简单,对某些人来说),但这种代码背后的原因可能更难看出。
总而言之,有几个指针。
我建议在掌握其基础知识之前,不要开始编写涉及并发的几乎不严重的代码。
请从围棋之旅的相关部分开始,然后转到围棋博客:
首先尝试使用更简单的示例。
- 1 回答
- 0 关注
- 93 浏览
添加回答
举报