Go 单个通道上有多个接收器。谁得到数据?
无缓冲信道阻塞接收机,直到信道上有数据可用。我不清楚在同一通道上的多个接收器(比如使用goroutines时)这种阻塞是如何工作的。我确信,只要该频道上没有发送数据,它们都会阻塞。Go 单个通道上有多个接收器。谁得到数据?,go,blocking,channel,Go,Blocking,Channel,无缓冲信道阻塞接收机,直到信道上有数据可用。我不清楚在同一通道上的多个接收器(比如使用goroutines时)这种阻塞是如何工作的。我确信,只要该频道上没有发送数据,它们都会阻塞。 但是,一旦我向该通道发送一个值,会发生什么?哪个接收器/goroutine将获得数据并因此解除阻塞?都是吗?第一排?随机?一个随机(非确定性)的人将收到它 见语言: “select”语句的执行分为几个步骤: 对于语句中的所有情况,receive操作的通道操作数以及send的通道和右侧表达式 语句在输入时按源代码顺序计
但是,一旦我向该通道发送一个值,会发生什么?哪个接收器/goroutine将获得数据并因此解除阻塞?都是吗?第一排?随机?一个随机(非确定性)的人将收到它 见语言: “select”语句的执行分为几个步骤:
默认情况下,goroutine通信为
同步
和无缓冲
:只有在有接收器接受该值时,发送才会完成。必须有一个接收器准备从通道接收数据,然后发送方可以直接将数据移交给接收器
因此,通道发送/接收操作将阻塞,直到另一端准备就绪:
1.频道上的发送操作会一直阻塞,直到同一频道有可用的接收器:如果没有接收器接收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在一个频道上接收,则发送方正在广播。每个接收器都应该能够同等地处理数据。因此,go运行时使用何种机制来决定许多goroutine接收器中的哪一个将运行Cf并不重要。但如果通道未缓冲,则每个发送的项目只运行一个 比赛条件?这样做安全吗?是的,当然,goroutine获得元素只是一种活泼。我不会称之为“比赛条件”。该术语通常定义为表示由于不安全并发访问变量而导致的意外行为。频道被设计成可以同时安全访问,一个无缓冲的频道上有多个阅读器没有问题。我认为你根本不需要这个术语,添加它只是混淆了问题。因为通道的内部结构将接收操作序列化,所以它本身并没有什么“快速性”,用CSP术语来说,这是一个不确定的选择。这与比赛条件不同。正如JimB所说,后者是偶然和有害的。如果您希望选择是确定性的,您可能需要使用N个通道,而不是1个,用于N个接收goroutine。
func receive(ch chan int) {
for {
fmt.Println(<- ch)
}
}
func main() {
ch := make(chan int)
go pump(ch)
receive(ch)
}