关闭频道与发送,例如一个空结构?

时间:2015-03-30 18:01:05

标签: go channel goroutine

我有一个通过通道连接的goroutine管道,这样每个goroutine都会触发另一个goroutine直到所有运行。更简单一点,想象两个goroutine AB,这样当A完成后,它应该告诉B它可以运行。

它工作正常,我尝试了一些变体,因为我学到了更多关于pipelines in Go的内容。

目前我有一个信令频道

ch := make(chan struct{})
go A(ch)
go B(ch)
...

B阻止了

func B(ch <-chan struct{}) {
    <-ch
    ...
完成后

A关闭

func A(ch chan struct{}) {
    defer close(ch)
    ...
}

这很好用,我也试过,而不是关闭,在struct{}中发送一个空结构A()

关闭频道或发送空结构有什么区别吗?哪种方式更便宜/更快/更好?

当然,在频道中发送任何其他类型会占用&#34;某些&#34;内存量,但是如何使用空结构?关闭只是频道的一部分,因此不会发送&#34;即使信息在goroutines之间传递,也是如此。

我很清楚过早优化。这只是为了理解事物,而不是为了优化任何事情。

也许有一种习惯性的Go方式可以做到这一点吗?

感谢您对此有任何澄清!

2 个答案:

答案 0 :(得分:2)

关闭频道表示该频道上不再有发送。它通常是可取的,因为在无意发送或关闭(编程错误)的情况下,您会在此之后感到恐慌。 close也可以向多个接收者发出信号,告知不再有消息,只需发送标记值即可轻松协调。

  

当然,在频道中发送任何其他类型会占用&#34;某些&#34;内存量,但是如何使用空结构?

无法保证它在非缓冲通道中占用任何额外的内存(它完全是一个实现细节)。发送阻止,直到接收可以继续。

  

关闭只是频道的一部分,因此不会发送&#34;即使信息在goroutines之间传递,也是如此。

此处没有优化,close只是可以发送到频道的另一种类型的消息。

每个构造都有明确的含义,你应该使用适当的构造。

  • 如果您需要向一个接收器发出信号,请发送一个标记值,并保持频道打开以发送更多值。

  • 如果这是最终消息,请关闭频道,可能发出多个接收器信号,发送或再次关闭将会出错。

答案 1 :(得分:0)

您可以通过多个goroutines从封闭频道接收它们,它们永远不会阻止。这是一个主要优势。这是 one_to_many模式

当许多并发运行者想要报告完成的事情时,

finish := make(chan struct{})可用于 many_to_one 模式,而局外人不会panic

这不是关于内存消耗。