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

go实现生产者消费者模型

作者头像
跑马溜溜的球
发布2020-12-07 14:45:40
4350
发布2020-12-07 14:45:40
举报
文章被收录于专栏:日积月累1024

这是一个单一生产者,多消费者的模型。该模型主要实现了任务调度和同步。 实际使用时需要修改的内容如下:

代码语言:javascript
复制
type Task struct{}  //自己实际需要的数据结构
producer()  //实际生产数据逻辑
consumer()  //实际处理逻辑

main()中的consumerNum(消费者个数), channelLen(通道长度)也可根据实际需要修改

代码如下:

代码语言:javascript
复制
package main

import (
	"fmt"
	"sync"
)

type Task struct {
	Data string
}

var wg sync.WaitGroup

//生产逻辑
func producer(tasks chan Task) {
	t := Task{}

	for i := 62; i < 72; i++ {
		t.Data = string(i)
		tasks <- t
	}
}

func producerDispatch(tasks chan Task) {
	defer close(tasks)

	producer(tasks)
}

//消费数据处理逻辑
func consumer(task Task) {
	fmt.Printf("consum task:%v\n", task)
}

func consumerDispatch(tasks chan Task) {
	defer wg.Done()

	for task := range tasks {
		consumer(task)
	}
}

func main() {
	//消费者个数
	var consumerNum = 10
	var channelLen = 50

	tasks := make(chan Task, channelLen)

	go producerDispatch(tasks)

	for i := 0; i < consumerNum; i++ {
		wg.Add(1)
		go consumerDispatch(tasks)
	}

	wg.Wait()
	fmt.Println("all done")
}

说明:

  1. 生产者完成任务后调用close关闭通道
  2. 因为通道关闭,所以消费者在取完所有任务后,会退出取任务的for循环。
  3. 主线程main, 通过Wait()保证了在所有任务处理完后才退出。
  4. wg.Add必须放在main中。不然,有可能main执行完了,producerDispatch,consumerDispatch协程还没被调度到,这样就直接打印“all done”退出了。这也是在实际过程中踩的一个坑。

不足: 刚学习go, 没想到如何将其封成一个类似php的class的东西,方便使用。也许interface是条路? 有好思路的同学欢迎交流。

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档