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

举报
Regan Yue 发表于 2021/08/23 15:14:44 2021/08/23
【摘要】 Golang高并发:生产者消费者模型我们本篇博文主要通过几个例子来介绍生产者消费者模型。 案例1下面看看第一个例子中的生产者协程。//生产者协程 go func() { for { product := strconv.Itoa(time.Now().Nanosecond()) chanShop <- "商品" + product fmt.Println("生产了商品",p...

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

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

案例1

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

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

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

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

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

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

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

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

//主协程
	for  {
		time.Sleep(time.Second)
	}

运行结果是

消费了产品 商品607861100
生产了商品 607861100
生产了商品 607929500
消费了产品 商品607929500
生产了商品 608013000
消费了产品 商品608013000
生产了商品 608018400
消费了产品 商品608018400

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

案例2

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

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

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

然后先来看看生产者协程

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个产品放入仓库,然后关闭了仓库。

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

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

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

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

func consumer(chanShop chan string)  {
	for{
		product := <-chanShop
		fmt.Println("消费了产品",product)
	}
}

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

然后看看运行结果

生产了产品 605763200物流完成转运 产品605763200消费了产品 产品605763200生产了产品 605826700物流完成转运 产品605826700消费了产品 产品605826700生产了产品 619889800物流完成转运 产品619889800消费了产品 产品619889800生产了产品 619906200物流完成转运 产品619906200消费了产品 产品619906200生产了产品 627948700物流完成转运 产品627948700消费了产品 产品627948700

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

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

	close(chanShop)	fmt.Println("商品转运完毕!商店已关张!")

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

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

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

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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