Go 关闭通道与发送(例如,空结构)的对比?

Go 关闭通道与发送(例如,空结构)的对比?,go,channel,goroutine,Go,Channel,Goroutine,我有一个通过通道连接goroutine的管道,这样每个goroutine都将触发另一个goroutine,直到所有goroutine都运行为止。更简单地说,想象两个goroutineA和B,这样当A完成时,它应该告诉B它可以运行 它的工作很好,我已经尝试了一些变种,因为我已经了解了更多 目前我有一个信号通道 ch := make(chan struct{}) go A(ch) go B(ch) ... B阻塞 func B(ch <-chan struct{}) { <-c

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

它的工作很好,我已经尝试了一些变种,因为我已经了解了更多

目前我有一个信号通道

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

func B(ch <-chan struct{}) {
    <-ch
    ...
这很好,我还尝试在
A()
中发送一个空的struct
struct{}
,而不是关闭

关闭通道和发送空结构之间有什么区别吗?两种方法都更便宜/更快/更好吗

当然,在通道中发送任何其他类型都会占用“一些”内存,但是空结构如何呢?Close只是通道的一部分,所以即使在goroutine之间传递信息,也不会“发送”

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

也许有一种惯用的围棋方式可以做到这一点


感谢您对此的任何澄清

关闭一个频道表示该频道将不再有发送。这通常是比较可取的,因为在发生意外发送或关闭(编程错误)的情况下,在这一点之后,您会感到恐慌。
close
还可以向多个接收者发出信号,表示没有更多的消息了,而仅仅发送哨兵值是无法轻松协调这些消息的

当然,在通道中发送任何其他类型都会占用“一些”内存,但是空结构如何呢

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

Close只是通道的一部分,所以即使在goroutine之间传递信息,也不会“发送”

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

每个结构都有明确的含义,您应该使用适当的结构

  • 如果需要向一个接收器发送信号,则发送一个哨兵值,并保持通道打开以发送更多值

  • 如果这是最后一条消息,请关闭通道,可能会向多个接收器发送信号,如果再次发送或关闭,则会出错


您可以通过多个goroutine从封闭通道接收数据,它们永远不会阻塞。这是一个主要优势。这是一对多的模式

finish:=make(chan struct{})
可以在多对一模式中使用,当许多并发运行者想要报告所做的事情时,局外人不会惊慌失措


这与内存消耗无关。

谢谢你的回答。我知道“关闭”意味着什么,询问“代码>关闭(CH)<代码> VS代码> CH @ MurRekt:<代码>关闭<代码>是一个逻辑消息,一个特殊的值,承诺不再发送更多的值,您认为什么是消息?发送和关闭都只是操纵通道的内部状态,导致一个值被发送到接收器。我在Go源代码中查看了
close
的功能,它设置了一个标志,指示频道已关闭。@Uvelichtiel您不使用等待组来通知多对一完成吗?@murrekatt Sync wait group用于等待所有。但是你可以只对最终的获胜者感兴趣。在这种情况下,胜利者不应关闭频道,以免外人在关闭的频道上惊慌失措。相反,参赛者应该只向裁判员发出信号,然后由裁判员结束比赛。
func A(ch chan struct{}) {
    defer close(ch)
    ...
}