3 回答
TA贡献1820条经验 获得超9个赞
一个随机(非确定性)的人会收到它。
请参阅语言规范:
“select”语句的执行分几个步骤:
对于语句中的所有情况,接收操作的通道操作数以及发送语句的通道和右侧表达式在进入“选择”语句时按源顺序被计算一次。结果是一组要接收或发送的通道,以及要发送的相应值。无论选择哪个(如果有)通信操作进行,该评估中的任何副作用都会发生。带有简短变量声明或赋值的 RecvStmt 左侧的表达式尚未计算。
如果可以进行一个或多个通信,则通过统一伪随机选择选择可以进行的单个通信。 否则,如果存在默认情况,则选择该情况。如果没有默认情况,“select”语句会阻塞,直到至少有一个通信可以继续。
除非选择的情况是默认情况,否则将执行相应的通信操作。
如果选定的 case 是带有短变量声明或赋值的 RecvStmt,则评估左侧表达式并分配接收到的值(或多个值)。
执行所选案例的语句列表。
TA贡献1848条经验 获得超10个赞
默认情况下,goroutine 通信是synchronousand unbuffered: 发送不会完成,直到有接收者接受该值。必须有一个接收者准备好从通道接收数据,然后发送者可以将它直接交给接收者。
所以通道发送/接收操作阻塞,直到另一端准备好:
1.通道上的发送操作会阻塞,直到接收器可用于同一通道:如果没有接收器的值 on ch,则不能将其他值放入通道。反之亦然:ch当通道不为空时,不能发送新值!因此发送操作将等待直到ch再次可用。
2.通道的接收操作阻塞,直到发送方可用于同一通道:如果通道中没有值,则接收方阻塞。
下面的例子说明了这一点:
package main
import "fmt"
func main() {
ch1 := make(chan int)
go pump(ch1) // pump hangs
fmt.Println(<-ch1) // prints only 0
}
func pump(ch chan int) {
for i:= 0; ; i++ {
ch <- i
}
}
因为没有接收器,goroutine 挂起并只打印第一个数字。
为了解决这个问题,我们需要定义一个新的 goroutine,它以无限循环的方式从通道中读取数据。
func receive(ch chan int) {
for {
fmt.Println(<- ch)
}
}
然后在main():
func main() {
ch := make(chan int)
go pump(ch)
receive(ch)
}
- 3 回答
- 0 关注
- 176 浏览
添加回答
举报