单个通道上的多个接收器。谁得到数据?

无缓冲通道阻塞接收器,直到通道上有数据可用。我不清楚这种阻塞是如何与同一通道上的多个接收器一起工作的(比如在使用 goroutines 时)。我敢肯定,只要该通道上没有发送数据,它们都会阻塞。
但是,一旦我向该通道发送单个值会发生什么?哪个接收器/goroutine 将获取数据并因此解除阻塞?他们都?第一个?随机的?

慕森卡
浏览 177回答 3
3回答

慕妹3146593

一个随机(非确定性)的人会收到它。请参阅语言规范:“select”语句的执行分几个步骤:对于语句中的所有情况,接收操作的通道操作数以及发送语句的通道和右侧表达式在进入“选择”语句时按源顺序被计算一次。结果是一组要接收或发送的通道,以及要发送的相应值。无论选择哪个(如果有)通信操作进行,该评估中的任何副作用都会发生。带有简短变量声明或赋值的 RecvStmt 左侧的表达式尚未计算。如果可以进行一个或多个通信,则通过统一伪随机选择选择可以进行的单个通信。 否则,如果存在默认情况,则选择该情况。如果没有默认情况,“select”语句会阻塞,直到至少有一个通信可以继续。除非选择的情况是默认情况,否则将执行相应的通信操作。如果选定的 case 是带有短变量声明或赋值的 RecvStmt,则评估左侧表达式并分配接收到的值(或多个值)。执行所选案例的语句列表。

慕桂英546537

默认情况下,goroutine 通信是synchronousand unbuffered: 发送不会完成,直到有接收者接受该值。必须有一个接收者准备好从通道接收数据,然后发送者可以将它直接交给接收者。所以通道发送/接收操作阻塞,直到另一端准备好:1.通道上的发送操作会阻塞,直到接收器可用于同一通道:如果没有接收器的值 on ch,则不能将其他值放入通道。反之亦然:ch当通道不为空时,不能发送新值!因此发送操作将等待直到ch再次可用。2.通道的接收操作阻塞,直到发送方可用于同一通道:如果通道中没有值,则接收方阻塞。下面的例子说明了这一点:package mainimport "fmt"func main() {&nbsp; &nbsp; ch1 := make(chan int)&nbsp; &nbsp; go pump(ch1) // pump hangs&nbsp; &nbsp; fmt.Println(<-ch1) // prints only 0}func pump(ch chan int) {&nbsp; &nbsp; for i:= 0; ; i++ {&nbsp; &nbsp; &nbsp; &nbsp; ch <- i&nbsp; &nbsp; }}因为没有接收器,goroutine 挂起并只打印第一个数字。为了解决这个问题,我们需要定义一个新的 goroutine,它以无限循环的方式从通道中读取数据。func receive(ch chan int) {&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(<- ch)&nbsp; &nbsp; }}然后在main():func main() {&nbsp; &nbsp; ch := make(chan int)&nbsp; &nbsp; go pump(ch)&nbsp; &nbsp; receive(ch)}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go