去选择 channel 并收集结果

标签 go

这是代码片段:

for !done && outstanding > 0 {
  select {
  case signals := <- input:
    outstanding++
    go func() { results <- FFT(signals) }()
  case res <- results:
    outstanding--
    output <- results
  case <- ctx.Done():
    done = true
  }
}

In this video Richard Fliam 说:

In this code snippet we're farming out some work to multiple cores for FFTs. When cancellation is done on all outstanding results are collected and sent before the function returns. If we did not collect the results in this case we would have a memory leak. You can see that's because I'm not selecting against the Done context in that go func.

但是当有一些未完成的结果(未完成的变量大于零)并且操作被取消时,done 变量被设置为 true,然后 for 循环的条件将评估为 false,因此未完成的结果将不被收集。

他为什么说出色的结果是在函数返回之前收集的?

我是新来的。也许我不明白一些基本概念。

更新:

如果 for 循环的条件如下,IMO 始终会收集未完成的结果:

// logical OR instead of AND
for !done || outstanding > 0 { ... }

因为当操作被取消并且仍有一些未完成的结果时,for 循环的条件将评估为真。如果所有未完成的结果都到达,则 for 循环将结束。

最佳答案

所有结果收集到这一行output <- results

case res <- results:
    outstanding--
    output <- results

这部分片段是错误的,因为那是双重接收 channel 。

必须是:

case res <- results:
    outstanding--
    output <- res

关于去选择 channel 并收集结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32018577/

相关文章:

Go protobuf 包冲突

pointers - 为什么带有指针和非指针接收器的方法在 Go 中不能具有相同的名称?

algorithm - Go:多个 len() 调用与性能?

go - 尝试使用 interface{} slice 来选择随机元素

go - 为什么 golang 移位运算符优先于加法?

go - 如何拆分 fmt.sprintf 的长行

function - golang : http. get() 返回

git - 当 GOPATH 强制您将代码放入/go 文件夹时,如何将所有相关项目放在一起

go - 将 if 语句转换为短语句

go - 如何从远程机器连接到kubernetes pod?