从生产者消费者模型深入学习golang channel
  热度 °
从生产者消费者模型探究回顾golang channel注意事项; 实例探究no buffer及buffer channel;
channel
golang channel 分为无缓冲channel及缓冲channel, 具体体现在创建channel时是否制定channel size,
1 | //no buffer channel |
- 无缓冲channel 默认channel大小为1, 写入一个值后需要被读取之后才能继续写入, 否则写阻塞;
- 缓冲channel 的大小是初始时的bufSize, 可连续写入bufSize值, 然后等待读取, 当len(channel) < bufSize时才可以继续写入, 否则写阻塞;
- channel 中没有值时 则读阻塞;
- channel 常用在同步, pipe, 无锁设计等场景中;
写值
1 | ch <- in |
- 非写阻塞时可以写入值;
读值
1 | out := <-ch |
- 非读阻塞时可以读取值;
- 当ok 为false时, 表示channel已被关闭;
关闭
1 | close(ch) |
- 只要当写channel写入完毕后则应立即关闭channel; 而读channel则可以不需要处理;
更多参考Range and close
for循环读
1 | for x := range ch { |
- 当使用for range 从管道读取数据的时候,管道没有数据,那么循环会阻塞,只有当管道被关闭的时候,for 循环才会结束
生产者消费者模型
1 | //producer_consumer.go |
测试case
1 | //producer_consumer_test.go |
output
1 | ➜ make bench |
更多分析及完整源码可参见 github-channel
总结
- 回顾了channel两种类型(no buffer/buffer channel);
- 只有写channel需要close, 而读channel 则可以不需要关心; 需要注意channel 在多个goroutine中的close问题;
- channel 是非常常用的一种结果, 常见于业务同步, buffer pipe, timeout, 无锁设计等场景中;
作者署名:朴实的一线攻城狮
本文标题:从生产者消费者模型深入学习golang channel
本文出处:http://researchlab.github.io/2018/11/08/producer-consumer-go-channel/
版权声明:本文由Lee Hong创作和发表,采用署名(BY)-非商业性使用(NC)-相同方式共享(SA)国际许可协议进行许可,转载请注明作者及出处, 否则保留追究法律责任的权利。