代码A
package main import ( "fmt" "time" ) func generator() chan int { out := make(chan int) go func() { i := 0 for { //time.Sleep(time.Duration(rand.Intn(8500)) * time.Millisecond) time.Sleep(1 * time.Second) out <- i i++ } }() return out } func worker(id int, c chan int) { for n := range c { time.Sleep(time.Second) fmt.Printf("Worker %d received %d\n", id, n) } } func createWorker(id int) chan<- int { c := make(chan int) go worker(id, c) return c } func main() { var c1, c2 = generator(), generator() var workChannel = createWorker(0) var values []int tm := time.After(10 * time.Second) tick := time.Tick(time.Second) for { var activeWorker chan<- int var activeValue int if len(values) > 0 { activeWorker = workChannel activeValue = values[0] } select { case n := <-c1: println("c1") values = append(values, n) case n := <-c2: println("c2") values = append(values, n) case activeWorker <- activeValue: println(activeValue) fmt.Println("values :", values, " activeValue:", activeValue) println(len(values)) values = values[1:] case <-time.After(800 * time.Millisecond): fmt.Println("timeout") case <-tick: fmt.Println( "queue len =", len(values)) case <-tm: fmt.Println("bye") return } } }
代码B
package main import ( "fmt" "math/rand" "time" ) func generator() chan int { out := make(chan int) go func() { i := 0 for { time.Sleep(time.Duration(rand.Intn(1500)) * time.Millisecond) //time.Sleep(1 * time.Second) out <- i i++ } }() return out } func worker(id int, c chan int) { for n := range c { time.Sleep(time.Second) fmt.Printf("Worker %d received %d\n", id, n) } } func createWorker(id int) chan<- int { c := make(chan int) go worker(id, c) return c } func main() { var c1, c2 = generator(), generator() var workChannel = createWorker(0) var values []int //tm := time.After(10 * time.Second) tick := time.Tick(time.Second) for { // var activeWorker chan<- int var activeValue int if len(values) > 0 { // activeWorker = workChannel activeValue = values[0] } select { case n := <-c1: values = append(values, n) case n := <-c2: values = append(values, n) case workChannel <- activeValue: fmt.Println("values :", values, " activeValue:", activeValue) values = values[1:] case <-tick: fmt.Println( "queue len =", len(values)) //case <-tm: // fmt.Println("bye") // return } } }
代码A、B 晃眼一看基本没有什么问题,都是两个生产者一个消费者,A只是多了 activeWorker 的临时变量,中间做了转换,但是问题就出在这里,由于对于nil channel的理解不够,所以一直认为 nil channel是可以传值的,但是百思不得其解,为什么一直报错。
网上找了教程,看了总结,才发现,原理竟然如此简单,论基础的重要性。。。。。。