回答

收藏

多个 goroutine 监听一个通道

技术问答 技术问答 334 人阅读 | 0 人回复 | 2023-09-12

我有多个 goroutine 试图同时在同一频道接收。最后一个 似乎开始在通道上接收goroutine 获得值。这是语言规范中的某个地方还是未定义的行为?
  |1 M- E; k+ s1 p4 ^4 N

    6 k5 Z" ], D; `& g. u" w7 L/ b5 c
  • c := make(chan string)for i := 0; i 输出:[code]goroutine 4. f7 M, \$ c7 ~! D
编辑:
- C4 k! ?& k7 S7 [我意识到这比我想象的要复杂。消息在所有 goroutine 中传递。
  X) ~/ U7 q" E  K

    ; I6 t( s# v5 c2 q
  • c := make(chan string)for i := 0; i 输出:[code]original,hi from 0,hi from 1,hi from 2,hi from 3,hi from 4- t' \/ a( K2 _, a
注意:    最新版本的 以上输出Go 已过时(见评论). S, d7 x' Z$ Z
                                                                # P' p6 b: R5 G) }2 f
    解决方案:                                                                , M, v, Q) l1 P0 J5 f; t! z
                                                                是的,这很复杂,但有一些经验规则可以让事情变得更简单。+ r& O' r) }$ p- Q0 }5 G7 ~8 a
更喜欢为传递给 go-routines正式参数用于通道,而不是全局访问通道。这样可以获得更多的编译检查和更好的模块化。
8 ^5 M5 N  z# L9 ?" v避免在特定 go 例程(包括主要例程)读取和写入同一通道。否则,死锁的风险要大得多。
这是应用这两个标准的程序的替代版本。这个案例在一个频道上展示了许多作者和读者:
" b' \  ]% \1 T  ~) X. v( C1 d1 k[code]c := make(chan string)for i := 1; i http://play.golang.org/p/quQn7xePLw/ l( q" O4 R6 L' ]$ v2 u1 A+ S
它创建了五个 写入单个通道go-routine,每个都写了五次。go-routine 阅读所有 25 - 你可能会注意到它们的顺序通常不是顺序(即并发性明显)。
! O$ W, ^0 n* ~这个例子演示了 Go 通道的一个特点:多个作者可以共享一个通道;Go 自动交错消息。
6 _9 y! B6 y( x) P5 G这也适用于一个通道上的写入器和多个读取器,如下面的第二个示例所示:; C% i. l, C4 Z
[code]c := make(chan int)var w sync.WaitGroupw.Add(5)for i := 1; i 第二个例子包括在主足程中等待,否则及时退出和其他五个足程将提前终止(由于olov此校正)。' v# K( y/ ?+ j! Z/ [4 V7 V
在这两个例子中,不需要缓冲。仅仅将缓冲视为性能增强器通常是一个很好的原则。如果你的程序没有锁定没有缓冲区不会发生死锁与缓冲区是(但反之亦然并不总是正确的)。所以,作为它,另一个经验规则,开始时不要缓冲,然后根据需要稍后添加
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则