一个通道的操作是否会影响另一个通道的操作?

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

Is it one channel ops affect another channel ops

问题

我写了这段简单的代码,试图了解通道的工作原理。如果在发送通道b之后发送通道c,最后一个例程中的通道不会被发送。

我有两个通道,通道c用于将通道b分割为4个切片的部分。

  1. package main
  2. import (
  3. "fmt"
  4. "strconv"
  5. )
  6. func runner(idx int, c chan []int, b chan []int) {
  7. var temp []int
  8. fmt.Println("runner " + strconv.Itoa(idx))
  9. bucket := <-b
  10. for k, v := range bucket {
  11. if v != 0 {
  12. temp = append(temp, v)
  13. bucket[k] = 0
  14. }
  15. if len(temp) == 5 {
  16. break
  17. }
  18. }
  19. // 如果在发送通道b之后发送通道c,奇怪的条件下,最后一个通道不会被发送
  20. b <- bucket
  21. c <- temp
  22. // 如果在发送通道c之后发送通道b,这样是正确的
  23. // c <- temp
  24. // b <- bucket
  25. }
  26. func printer(c chan []int) {
  27. for {
  28. select {
  29. case msg := <-c:
  30. fmt.Println(msg)
  31. //time.Sleep(time.Second * 1)
  32. }
  33. }
  34. }
  35. func main() {
  36. c := make(chan []int, 5)
  37. bucket := make(chan []int)
  38. go runner(1, c, bucket)
  39. go runner(2, c, bucket)
  40. go runner(3, c, bucket)
  41. go runner(4, c, bucket)
  42. bucket <- []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
  43. go printer(c)
  44. var input string
  45. fmt.Scanln(&input)
  46. }

希望对你有帮助!

英文:

I made this simple code, trying to know how's channel works, somehow if channel c is sent after channel b is sent, channel in last routine is not being sent,

I have 2 channel, channel c is for spliting channel b to 4 part of slice.

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. &quot;strconv&quot;
  5. )
  6. func runner(idx int, c chan []int, b chan []int) {
  7. var temp []int
  8. fmt.Println(&quot;runner &quot; + strconv.Itoa(idx))
  9. bucket := &lt;-b
  10. for k, v := range bucket {
  11. if v != 0 {
  12. temp = append(temp, v)
  13. bucket[k] = 0
  14. }
  15. if len(temp) == 5 {
  16. break
  17. }
  18. }
  19. //Strange condition if channel c is sent after channel b is sent,
  20. //somehow the last chan is not being sent
  21. b &lt;- bucket
  22. c &lt;- temp
  23. //this is right if channel b is sent after channel c is sent
  24. //c &lt;- temp
  25. //b &lt;- bucket
  26. }
  27. func printer(c chan []int) {
  28. for {
  29. select {
  30. case msg := &lt;-c:
  31. fmt.Println(msg)
  32. //time.Sleep(time.Second * 1)
  33. }
  34. }
  35. }
  36. func main() {
  37. c := make(chan []int, 5)
  38. bucket := make(chan []int)
  39. go runner(1, c, bucket)
  40. go runner(2, c, bucket)
  41. go runner(3, c, bucket)
  42. go runner(4, c, bucket)
  43. bucket &lt;- []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
  44. go printer(c)
  45. var input string
  46. fmt.Scanln(&amp;input)
  47. }

答案1

得分: 3

bucket := make(chan []int)

你的 b 通道的容量是0。这意味着每当你向该通道发送数据时,通道立即变满,并且会阻塞直到接收者读取通道。

当只剩下一个运行程序时,没有人会调用 bucket := <-b 来读取最后一个桶,因此最后一个 goroutine 将永远卡在 b <- bucket 这一行上,因此下一行的 c <- temp 对于这个最后一个 goroutine 永远不会被调用。

英文:
  1. bucket := make(chan []int)

Your b channel's capacity is 0. This means whenever you send something to this channel, the channel is full immediately and will block until a receiver reads the channel.

When there is only one runner left, no one is going to call bucket := &lt;-b to read the last bucket, thus this last goroutine is stuck forever on the b &lt;- bucket line, and thus the next line c &lt;- temp will never be called for this last goroutine.

huangapple
  • 本文由 发表于 2017年4月1日 12:18:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/43152776.html
匿名

发表评论

匿名网友

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

确定