去选择频道并收集结果。

huangapple go评论64阅读模式
英文:

Go select channels and collect results

问题

以下是代码片段的翻译:

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
  }
}

在这个视频中,Richard Fliam说:

在这段代码中,我们将一些工作分配给多个核心进行FFT计算。当取消操作完成后,在函数返回之前,所有未完成的结果都会被收集并发送出去。如果我们在这种情况下不收集结果,就会导致内存泄漏。你可以看到,这是因为在那个go函数中,我没有选择使用Done上下文。

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

为什么他说未完成的结果在函数返回之前被收集?

我对Go语言还不熟悉。也许我没有理解某些基本概念。

更新:

在我看来,如果for循环的条件如下所示,未完成的结果将始终被收集:

// 逻辑上的或运算符而不是与运算符
for !done || outstanding > 0 { ... }

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

英文:

Here's the code snippet:

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

In this video Richard Fliam says that:

> 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.

But when there are some outstanding results (the outstanding variable is greater than zero) and the operation is cancelled then the done variable is set to true and then the condition of the for loop would evaluate to false, so the outstanding results would not be collected.

Why does he say that the outstanding results are collected before the the function returns?

I'm new to go. Maybe I don't understand something fundamental concept.

Update:

IMO the outstanding results would always be collected if the condition of the for loop was the following:

// logical OR instead of AND
for !done || outstanding &gt; 0 { ... }

Because when the operation is cancelled and there are still some outstanding results the condition of the for loop would evaluate to true. If all outstanding results arrive the for loop will end.

答案1

得分: 2

这一行代码收集了所有的结果:output <- results

以下是修正后的代码片段,原因是接收通道的变量名错误:

<!-- language: go -->
case res <- results:
    outstanding--
    output <- res

修正后的代码中,接收通道的变量名应为res,而不是results

英文:

all results collected this line output &lt;- results

<!-- language: go -->

case res &lt;- results:
    outstanding--
    output &lt;- results

this part of snippet is wrong, because then the double recieved chanel.

Must be:

<!-- language: go -->

case res &lt;- results:
    outstanding--
    output &lt;- res

huangapple
  • 本文由 发表于 2015年8月15日 05:00:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/32018577.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定