英文:
How does the keyword "select" operate in golang?
问题
我执行了下面的代码,其中包含select
:
func fibonacci(c, quit chan int) {
x, y := 0, 1
for {
select {
case c <- x:
fmt.Printf("x = %d, y = %d \n", x, y)
x, y = y, x+y
case <-quit:
//fmt.Println(<-c)
fmt.Println("quit")
return
}
}
}
func main() {
c := make(chan int)
quit := make(chan int)
go func() {
for i := 0; i < 10; i++ {
fmt.Println(<-c)
}
quit <- 0
}()
fibonacci(c, quit)
}
为什么select
在第10次迭代时停止?c <- x
操作不应该始终可行并计算无限的斐波那契数吗?
英文:
I executed the code below which has select
in it:
func fibonacci(c, quit chan int) {
x, y := 0, 1
for {
select {
case c <- x:
fmt.Printf("x = %d, y = %d \n", x, y)
x, y = y, x+y
case <-quit:
//fmt.Println(<-c)
fmt.Println("quit")
return
}
}
}
func main() {
c := make(chan int)
quit := make(chan int)
go func() {
for i := 0; i < 10; i++ {
fmt.Println(<-c)
}
quit <- 0
}()
fibonacci(c, quit)
}
Why does select
stop on the 10th iteration?
Isn't the c <- x
operation always possible and should calculate the Fibonacci numbers to infinity?
答案1
得分: 2
通道c
是无缓冲的,因此只有在存在并发的<- c
时,c <- x
才能继续执行。
此外,如果c
被缓冲并且缓冲区足够大,select
语句不会总是选择它,因为select
会随机选择通道。
英文:
The channel c
is unbuffered and thus c <- x
can only proceed while there is a concurrent <- c
.
In addition, if c
was buffered with a large enough buffer, the select
would not always choose it since select
chooses randomly.
答案2
得分: 0
感谢你找到这篇文章并理解了通道的工作原理。
所以:
-
无缓冲通道的大小为1。只有当有线程等待该通道时,才能将某个值插入无缓冲通道。因此,如果有线程请求该通道(<-c),则
c <- x
将起作用。否则,插入操作将不可能/被锁定。这就是为什么当你向通道中输入某个值时,没有人接收它会导致死锁的原因。你试图将某个值放入通道中,代码等待(锁定),等待有人接收,但没有人在那里。 -
另一方面,带缓冲的通道可以容纳多个值。你可以向它们输入
c <- x c <- y
,它不会锁定,等待有人从中获取值。在这种情况下,当通道已满(尝试向其中推送某些内容)且可能的接收方被阻塞,或者当通道为空(尝试接收某些内容)且所有可能的发送方被阻塞时,死锁可能发生。
英文:
Thanks for the answers I found this article and understand how channels work
So:
- Unbuffered channels have size of 1. And also operation of inserting something to unbuffered channel is possible if and only if someone is waiting for him. So
c <- x
would work if some thread asks for this channel (<-c
). Otherwise inserting is impossible/would be locked. This is why when you are feeding something in the channel and noone is receiving it causes a deadlock. You are trying to put some value in the channel, code waits (locks) for someone to receive, but there is noone there. - On the other hand buffered channels can eat several values. You could feed them
c <- x c <-y
and it would not lock, waiting for someone to catch the value from it. Here deadlock can occur when channel is full (trying to push something there) and possible receivers are blocked or when channel is empty (trying to receive something) and all possible senders are blocked.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论