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

举报
Regan Yue 发表于 2021/08/24 10:48:53 2021/08/24
【摘要】 Golang:再谈生产者消费者模型那假如我们想生产完了之后在一次性消费呢?怎么实现?那我们就出现了调度的情形。消费者等生产者生产完毕的信号,只有生产者给消费者发送信号,消费者才能消费,不然消费者一直阻塞。 主函数我们先来看看主函数:func main() { chanShop := make(chan string,10) chanTel := make(chan int) go Pr...

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

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。