我有一个通过通道连接的goroutine管道,这样每个goroutine都会触发另一个goroutine直到所有运行。更简单一点,想象两个goroutine A
和B
,这样当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方式可以做到这一点吗?
感谢您对此有任何澄清!
答案 0 :(得分:2)
关闭频道表示该频道上不再有发送。它通常是可取的,因为在无意发送或关闭(编程错误)的情况下,您会在此之后感到恐慌。 close
也可以向多个接收者发出信号,告知不再有消息,只需发送标记值即可轻松协调。
当然,在频道中发送任何其他类型会占用&#34;某些&#34;内存量,但是如何使用空结构?
无法保证它在非缓冲通道中占用任何额外的内存(它完全是一个实现细节)。发送阻止,直到接收可以继续。
关闭只是频道的一部分,因此不会发送&#34;即使信息在goroutines之间传递,也是如此。
此处没有优化,close
只是可以发送到频道的另一种类型的消息。
每个构造都有明确的含义,你应该使用适当的构造。
如果您需要向一个接收器发出信号,请发送一个标记值,并保持频道打开以发送更多值。
如果这是最终消息,请关闭频道,可能发出多个接收器信号,发送或再次关闭将会出错。
答案 1 :(得分:0)
您可以通过多个goroutines从封闭频道接收它们,它们永远不会阻止。这是一个主要优势。这是 one_to_many模式。
当许多并发运行者想要报告完成的事情时, finish := make(chan struct{})
可用于 many_to_one 模式,而局外人不会panic
。
这不是关于内存消耗。