写点什么

Golang:再谈生产者消费者模型

用户头像
Regan Yue
关注
发布于: 4 小时前
Golang:再谈生产者消费者模型

Golang:再谈生产者消费者模型

那假如我们想生产完了之后在一次性消费呢?怎么实现?那我们就出现了调度的情形。消费者等生产者生产完毕的信号,只有生产者给消费者发送信号,消费者才能消费,不然消费者一直阻塞。

主函数

我们先来看看主函数:


func main() {  chanShop := make(chan string,10)  chanTel  := make(chan int)    go Producer(chanShop,chanTel)  go Consumer(chanShop,chanTel)
for { time.Sleep(time.Second) }}
复制代码


chanTel没有缓存能力,我们之前说的,如果不往里写,那根本就不能读。所以被阻塞的那条消费者协程在读取前几乎不占用资源。

生产者协程

再来看看生产者协程:


func Producer(chanShop chan string,chanTel chan int)  {  runtime.GOMAXPROCS(2)  for i:=0;i<10;i++ {    product := strconv.Itoa(time.Now().Nanosecond())    chanShop <- "产品"+product    fmt.Println("生产了产品",product)    time.Sleep(time.Second)  }    close(chanShop)  fmt.Println("生产完毕")  chanTel <- 123456789  fmt.Println(123456789,"呼出电话")}
复制代码


生产 10 个商品,生产完毕之后,就开始打电话,给消费者协程打电话。生产者协程给chanTel写入东西,阻塞的消费者协程立刻就通顺了,来看看消费者协程的内容吧!

消费者协程

func Consumer(chanShop chan string,chanTel chan int)  {  runtime.GOMAXPROCS(1)    tel := <- chanTel  fmt.Println("收到来电",tel)
for product := range chanShop{ fmt.Println("消费了产品",product) } fmt.Println("消费完毕")}
复制代码


消费者调用单核处理消费。当收到来电时,该协程就不阻塞了,马上消费产品!


看了上面的例子,你可能还会疑惑什么是生产者消费者问题,最后我们再来了解了解吧!

什么是生产者消费者问题

根据维基百科,生产者消费者问题是这样介绍的:


生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(Bounded-buffer problem),是一个多进程同步问题的经典案例。该问题描述了共享固定大小缓冲区的两个进程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。


我们这段代码只是简单的描述这个问题,在写入缓冲区完毕后,缓冲区大小为 10,我们就写入 10 个,然后就马上关闭chanShop,关闭后消费者协程就不会一直读而导致在缓冲区中空时尝试读取数据。

发布于: 4 小时前阅读数: 2
用户头像

Regan Yue

关注

还未添加个人签名 2020.08.12 加入

还未添加个人简介

评论

发布
暂无评论
Golang:再谈生产者消费者模型