回答

收藏

多个 goroutine 监听一个通道

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

我有多个 goroutine 试图同时在同一频道接收。最后一个 似乎开始在通道上接收goroutine 获得值。这是语言规范中的某个地方还是未定义的行为?
( W% s7 A. e) t7 S  |: o1 N. n

    7 G- N1 f( g! `6 c
  • c := make(chan string)for i := 0; i 输出:[code]goroutine 4/ R5 ~9 }" T! w
编辑:2 d! k; a7 I- d  b
我意识到这比我想象的要复杂。消息在所有 goroutine 中传递。
* J2 o1 ]2 J# P8 o1 V

    9 O2 `/ U% ?8 z1 R1 _
  • 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
    . X9 E4 O" M- H
注意:    最新版本的 以上输出Go 已过时(见评论)
8 B  H: n4 S5 W+ e* N) N                                                                3 S2 z8 n( w& H$ b: \3 H9 T1 M
    解决方案:                                                                : d, W- T1 Z4 c. O9 [) `, A% T2 B
                                                                是的,这很复杂,但有一些经验规则可以让事情变得更简单。& P# ^6 P9 p- e
更喜欢为传递给 go-routines正式参数用于通道,而不是全局访问通道。这样可以获得更多的编译检查和更好的模块化。
; h$ C' n: G4 W4 r3 N# n/ d避免在特定 go 例程(包括主要例程)读取和写入同一通道。否则,死锁的风险要大得多。
这是应用这两个标准的程序的替代版本。这个案例在一个频道上展示了许多作者和读者:
4 t" v* D/ _  Y& ^: P. k[code]c := make(chan string)for i := 1; i http://play.golang.org/p/quQn7xePLw# }% y; ~' l1 j$ Z! {4 w
它创建了五个 写入单个通道go-routine,每个都写了五次。go-routine 阅读所有 25 - 你可能会注意到它们的顺序通常不是顺序(即并发性明显)。- T4 G% _% O' {  n$ z
这个例子演示了 Go 通道的一个特点:多个作者可以共享一个通道;Go 自动交错消息。9 M& T: O/ o8 ^! R& N
这也适用于一个通道上的写入器和多个读取器,如下面的第二个示例所示:
. p+ v5 B8 \7 G; t; B3 t& R[code]c := make(chan int)var w sync.WaitGroupw.Add(5)for i := 1; i 第二个例子包括在主足程中等待,否则及时退出和其他五个足程将提前终止(由于olov此校正)。4 Y+ J1 w- A, d/ u1 U" z
在这两个例子中,不需要缓冲。仅仅将缓冲视为性能增强器通常是一个很好的原则。如果你的程序没有锁定没有缓冲区不会发生死锁与缓冲区是(但反之亦然并不总是正确的)。所以,作为它,另一个经验规则,开始时不要缓冲,然后根据需要稍后添加
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则