首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Golang:再谈生产者消费者模型

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

作者头像
Regan Yue
发布2021-09-16 10:58:24
发布2021-09-16 10:58:24
6850
举报
文章被收录于专栏:ReganYue's BlogReganYue's Blog

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

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

主函数

我们先来看看主函数:

代码语言:javascript
复制
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没有缓存能力,我们之前说的,如果不往里写,那根本就不能读。所以被阻塞的那条消费者协程在读取前几乎不占用资源。

生产者协程

再来看看生产者协程:

代码语言:javascript
复制
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写入东西,阻塞的消费者协程立刻就通顺了,来看看消费者协程的内容吧!

消费者协程

代码语言:javascript
复制
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,关闭后消费者协程就不会一直读而导致在缓冲区中空时尝试读取数据。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/08/24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Golang:再谈生产者消费者模型
  • 主函数
  • 生产者协程
  • 消费者协程
  • 什么是生产者消费者问题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档