How does the keyword "select" operate in golang?

huangapple go评论64阅读模式
英文:

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 &lt;- x:
			fmt.Printf(&quot;x = %d, y = %d \n&quot;, x, y)
			x, y = y, x+y
		case &lt;-quit:
			//fmt.Println(&lt;-c)
			fmt.Println(&quot;quit&quot;)
			return
		}
	}
}

func main() {
	c := make(chan int)
	quit := make(chan int)
	go func() {
		for i := 0; i &lt; 10; i++ {
			fmt.Println(&lt;-c)
		}
		quit &lt;- 0
	}()
	fibonacci(c, quit)
}

Why does select stop on the 10th iteration?
Isn't the c &lt;- 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 &lt;- x can only proceed while there is a concurrent &lt;- 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. 无缓冲通道的大小为1。只有当有线程等待该通道时,才能将某个值插入无缓冲通道。因此,如果有线程请求该通道(<-c),则c <- x将起作用。否则,插入操作将不可能/被锁定。这就是为什么当你向通道中输入某个值时,没有人接收它会导致死锁的原因。你试图将某个值放入通道中,代码等待(锁定),等待有人接收,但没有人在那里。

  2. 另一方面,带缓冲的通道可以容纳多个值。你可以向它们输入c <- x c <- y,它不会锁定,等待有人从中获取值。在这种情况下,当通道已满(尝试向其中推送某些内容)且可能的接收方被阻塞,或者当通道为空(尝试接收某些内容)且所有可能的发送方被阻塞时,死锁可能发生。

英文:

Thanks for the answers I found this article and understand how channels work
So:

  1. 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 &lt;- x would work if some thread asks for this channel (&lt;-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.
  2. On the other hand buffered channels can eat several values. You could feed them c &lt;- x c &lt;-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.

huangapple
  • 本文由 发表于 2023年6月19日 20:49:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76506799.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定