• go channel理解不彻底遇到的问题nil channel


    代码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是可以传值的,但是百思不得其解,为什么一直报错。

          网上找了教程,看了总结,才发现,原理竟然如此简单,论基础的重要性。。。。。。

  • 相关阅读:
    大学毕业后拉开差距的原因 有可能影响你一生
    jsp文件上传、下载
    jsp读书笔记——servlet过滤器
    美国西点军校的育人之道
    jsp文件上传、下载
    2012年新浪微博用户密码泄露漏洞(图片解析)
    【转】Android的自动拨号程序,订票必备^_^
    清除arcsde空间垃圾数据以及解决sde图层名称被占用的问题
    【转】Android的自动拨号程序,订票必备^_^
    2012年新浪微博用户密码泄露漏洞(图片解析)
  • 原文地址:https://www.cnblogs.com/hoganhome/p/15735301.html
Copyright © 2020-2023  润新知