目录git
咱们经常使用的是无缓冲channel :github
make(chan type)
其实make() 建立chan的第二个参数可设置缓冲channel的大小。
上述语句等价于 make(chan type, 1) 即建立了一个缓冲区大小为1channelgolang
下面看有缓冲channel的两个例子.this
demo :
协程1 :每隔1s 往有10个缓冲的channel里面写一条msg,3d
协程2:每隔3s 取一条msg,code
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后才能写入。协程
实际场景中咱们可能不但愿程序阻塞,那么能够使用select来控制,当缓冲区满了后忽略该条msg继续执行咱们的程序。blog
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,而是msg7get