前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Golang高并发:生产者消费者模型

Golang高并发:生产者消费者模型

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

Golang高并发:生产者消费者模型

我们本篇博文主要通过几个例子来介绍生产者消费者模型。

案例1

下面看看第一个例子中的生产者协程。

代码语言:javascript
复制
//生产者协程
	go func() {
		for  {
			product := strconv.Itoa(time.Now().Nanosecond())
			chanShop <- "商品" + product
			fmt.Println("生产了商品",product)

			time.Sleep(1000 * time.Millisecond)
		}
	}()

生产者协程就是源源不断的生产,将时间转化为字符串,然后源源不断的产生产品字符串。此处用到了strconv.Itoa(),是将整型转换为字符串类型。time.Now()是当前的时间,而使用Nanosecond()是将其转换为纳秒。然后将得到的产品序列号字符串放入视频管道,然后输出生产了什么产品,然后睡一秒,然后接着生产。

至于消费者协程,我相信你已经猜到了是什么了,我们也来看一看吧。

代码语言:javascript
复制
//消费者协程
	go func() {
		for{
			product := <-chanShop
			fmt.Println("消费了产品",product)
			
			time.Sleep(time.Second)
		}
	}() 

每次从商品管道取一个产品,然后输出消费了什么产品,然后睡一秒,然后继续消费。

再来看看这个案例的主协程

代码语言:javascript
复制
//主协程
	for  {
		time.Sleep(time.Second)
	}

运行结果是

代码语言:javascript
复制
消费了产品 商品607861100
生产了商品 607861100
生产了商品 607929500
消费了产品 商品607929500
生产了商品 608013000
消费了产品 商品608013000
生产了商品 608018400
消费了产品 商品608018400

没错,源源不断的生产消费、生产消费。

案例2

我们再来看看第二个案例,这个案例,我们引入了”物流“的概念。

先上主函数给各位读者老爷看看吧:

代码语言:javascript
复制
func main() {
	chanStorage := make(chan string ,100)
	chanShop := make(chan string, 100)

	go producer(chanStorage)
	go logistics(chanStorage,chanShop)
	go consumer(chanShop)
	for  {
		time.Sleep(time.Second)
	}
}

主要是建立商店和物流两条管道,然后建立生产者、消费者、物流三条协程,然后主协程一直不go die

然后先来看看生产者协程

代码语言:javascript
复制
func producer(chanStorage chan string)  {
	for i:=0;i<10;i++{
		product := strconv.Itoa(time.Now().Nanosecond())
		chanStorage <- "产品"+product
		fmt.Println("生产了产品",product)
		time.Sleep(time.Second)
	}
	close(chanStorage)
}

和第一个案例一样,不过我们只生产10个产品放入仓库,然后关闭了仓库。

然后看看物流协程是干了些什么:

代码语言:javascript
复制
func logistics(chanStroge,chanShop chan string)  {
	for p:= range chanStroge{
		fmt.Println("物流完成转运",p)
		chanShop <- p
	}
    fmt.Println("商品转运完毕!")
}

源源不断扫描仓库,拿出商品然后将商品转运到商店。当生产者关闭仓库后,物流也停止转运了。

消费者不断在消费,然后看看消费者:

代码语言:javascript
复制
func consumer(chanShop chan string)  {
	for{
		product := <-chanShop
		fmt.Println("消费了产品",product)
	}
}

等来一件商品,就卖出去。

然后看看运行结果

代码语言:javascript
复制
生产了产品 605763200物流完成转运 产品605763200消费了产品 产品605763200生产了产品 605826700物流完成转运 产品605826700消费了产品 产品605826700生产了产品 619889800物流完成转运 产品619889800消费了产品 产品619889800生产了产品 619906200物流完成转运 产品619906200消费了产品 产品619906200生产了产品 627948700物流完成转运 产品627948700消费了产品 产品627948700

我们可以看到,生产、转运、消费几乎是同时的。

因为我们当物流公司停止运物资时,商店也要关门,所以在物流协程内加入:

代码语言:javascript
复制
	close(chanShop)	fmt.Println("商品转运完毕!商店已关张!")

然后继续把消费者的for循环替换成

代码语言:javascript
复制
for product := range chanShop{		//product := <-chanShop		fmt.Println("消费了产品",product)		fmt.Println()	}	fmt.Println("消费全部完毕!")

就能够只读取管道里面的商品。

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Golang高并发:生产者消费者模型
    • 案例1
      • 案例2
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档