Go协程间通信之 生产者-消费者模型
通信原则
Go开发有一个经常提及的原则:
不要通过共享内存来通信(互斥锁同步),而要用通信来共享内存。
前言
在其他模式的开发语言中,比如Java有个常见的生产者-消费者模式,通过多个线程池与多个BlockingQueue
进行交互,如LinkBlockedQueue
, ArrayBlockedQueue
等 ,由于队列内部通过锁机制帮我们集成了同步的功能,程序业务层不需要关心多线程对队列的竞争,所以可以放心的使用。
而来到Go这边,由于channel
天生具备同步的特性,结合上面提到的通信原则,也可以较简单的运用于生产者-消费模型。
示例
- 创建一个共享队列作为生产者消费者连接的管道
var (
//通信管道大小
QUEUE_SIZE = conf.OptiInt("ext.queueSize", 5)
//生产者并发度
PRODUCE_SIZE = conf.OptiInt("ext.prodSize", 3)
//消费者并发度
CONSUME_SIZE = conf.OptiInt("ext.consSize", 3)
)
//共享队列
msgQueue := make(chan []byte, QUEUE_SIZE)
- 消费端业务
/*
* CNum标识不同消费者的序号,由外部传入
*/
func Consume(CNum int, msg chan []byte) {
for value := range msg {
logrus.Infof("# Consumer CNum.%d, take cake with value: %s.", CNum