zoukankan      html  css  js  c++  java
  • golang的缓冲channel简单使用

    golang的缓冲channel简单使用


    我们常用的是无缓冲channel :

    make(chan type)
    

    其实make() 创建chan的第二个参数可设置缓冲channel的大小。
    上述语句等价于 make(chan type, 1) 即创建了一个缓冲区大小为1channel

    下面看有缓冲channel的两个例子.

    阻塞型

    demo :
    协程1 :每隔1s 往有10个缓冲的channel里面写一条msg,

    协程2:每隔3s 取一条msg,

    package main 
    
    import(
    	//"fmt"
    	"time"
    	"strconv"
    	log "github.com/astaxie/beego/logs"
    )
    
    func main() {
    	log.Debug("---main--- start")
    
    	msgs := make(chan string, 10)
    
    	i := 0
    
    	go func() {
    		time.Sleep(3*time.Second)
    
    		for {
    			time.Sleep(1*time.Second)
    			i++
    			msg := "msg " + strconv.Itoa(i)
    			msgs <- msg
    			log.Debug("------ put msg : ", msg)
    		}
    	}()
    
    	go func() {
    
    		for {
    
    			get := <- msgs
    
    			log.Debug("---------------- pop msg : ", get)
    
    			time.Sleep(3*time.Second)
    		}
    
    	}()
    
    	time.Sleep(100*time.Second)
    
    }
    

    可以看到当缓冲区满了以后,写channel的操作会阻塞在那里等待读端取走msg后才能写入。

    image.png

    非阻塞

    实际场景中我们可能不希望程序阻塞,那么可以使用select来控制,当缓冲区满了后忽略该条msg继续执行我们的程序。

    package main 
    
    import(
    	//"fmt"
    	"time"
    	"strconv"
    	log "github.com/astaxie/beego/logs"
    )
    
    func main() {
    	log.Debug("---main--- start")
    
    	msgs := make(chan string, 3)
    
    	i := 0
    
    	go func() {
    		time.Sleep(3*time.Second)
    
    		for {
    
    			time.Sleep(1*time.Second)
    			i++
    			msg := "msg " + strconv.Itoa(i)
    
    			select {
    				case msgs <- msg:
    					log.Debug("------ put msg : ", msg)
    				default :
    					log.Debug("-----msgs chan cache full sleep 1s-----")
    					log.Debug("-----ignore this msg-----> : ", msg)
    			}
    		}
    	}()
    
    	go func() {
    
    		for {
    
    			get := <- msgs
    
    			log.Debug("---------------- pop msg : ", get)
    
    			time.Sleep(3*time.Second)
    		}
    
    	}()
    
    	time.Sleep(100*time.Second)
    
    }
    

    可以看到,因为写端写入过快,再写入msg6时缓冲区已满,执行default丢弃了msg6,读端在取走msg5后, 取走的不是msg6,而是msg7

    image.png

  • 相关阅读:
    三十七、Java基础之JDBC
    三十六、Java基础之File类
    各种IoC框架下实现AOP
    Eclipse导出可执行Jar文件(包含第三方Jar包)
    设计模式(Patterns in Java)-解道
    MyBatis入门示例
    freemarker实例2
    freemarker小例子
    MyEclipse8.6 破解以及注册码
    myeclipse中java文件中文注释乱码问题
  • 原文地址:https://www.cnblogs.com/ailumiyana/p/11108170.html
Copyright © 2011-2022 走看看