2017-04-01 34 views
-2

我做了这个简单的代码,试图了解如何为频道的作品,不知何故,如果发送通道B之后发送通道c,在过去的常规通道没有被发送,它是一个通道OPS影响到另一个通道OPS

我有2个通道,通道c用于将通道b分成4部分。

package main 

import (
     "fmt" 
     "strconv" 
) 

func runner(idx int, c chan []int, b chan []int) { 
     var temp []int 
     fmt.Println("runner " + strconv.Itoa(idx)) 
     bucket := <-b 
     for k, v := range bucket { 
      if v != 0 { 
       temp = append(temp, v) 
       bucket[k] = 0 
      } 
      if len(temp) == 5 { 
       break 
      } 
     } 

     //Strange condition if channel c is sent after channel b is sent, 
     //somehow the last chan is not being sent 
     b <- bucket 
     c <- temp 

     //this is right if channel b is sent after channel c is sent 
    //c <- temp 
    //b <- bucket 

} 

func printer(c chan []int) { 
     for { 
      select { 
      case msg := <-c: 
       fmt.Println(msg) 
       //time.Sleep(time.Second * 1) 
      } 
     } 
} 

func main() { 

     c := make(chan []int, 5) 
     bucket := make(chan []int) 

     go runner(1, c, bucket) 
     go runner(2, c, bucket) 
     go runner(3, c, bucket) 
     go runner(4, c, bucket) 

     bucket <- []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20} 

     go printer(c) 

     var input string 
     fmt.Scanln(&input) 

} 
+0

这个代码实际上并不清楚你不清楚这个代码。你期望得到什么以及你实际得到了什么? – zerkms

+0

你有没有运行代码?请检查跑步者功能,如果你先发送到频道c然后b,你会有合适的条件,这是我不明白的,我希望有人会解释这个频道的行为 –

+0

“你会有合适的条件” ---这是问题的问题:你没有解释什么是“正确”,什么是“错误”。 PS:请尽量避免使用“c”,“u”,“b”和其他缩写。 – zerkms

回答

3
bucket := make(chan []int) 

b通道的容量为0.这意味着只要您送东西给这个通道,该通道是立即全面和将阻塞,直到接收器读取信道。

当只有一个亚军离开,没有人会打电话bucket := <-b阅读最后一个桶,因此这最后的goroutine被永远困在b <- bucket线,因此下一行c <- temp将永远不会被调用这最后够程。

+0

Ahhh我现在看到,没有其他例程读取通道'<-b',所以它会永久卡在'b < - bucket',所以然后我在打印机上做了更改FUNC用于读取b通道 'FUNC打印机(C瓒[] INT,b瓒[] INT){ 为{ 选择{ 情况下消息:= <-c: fmt.Println(MSG) //时间。睡眠(time.Second * 1) 情况下消息:= <-b: fmt.Println(MSG) } } }' –

+0

谢谢非常非常非常 –

+0

问题没有人读取的最后一个b通道所以它会卡住或阻止 –

相关问题