当前位置: 首页 > article >正文

【go每日一题】 实现生产者消费者模式

基本描述

golang使用并发编程,实现一个生产者消费者模式,消费的任务耗时1-3秒,希望最终10秒内能够消费尽可能多的任务

代码

package test

import (
	"fmt"
	"math/rand"
	"testing"
	"time"
)

type ConsumeTask struct {
	id       int
	execFunc func()
}

type Producer struct {
	id int
	ch chan *ConsumeTask
}

type Consumer struct {
	id int
	ch chan *ConsumeTask
}

func TestProducerConsumer(t *testing.T) {

	taskCh := make(chan *ConsumeTask, 100)
	defer close(taskCh)

	producers := make([]*Producer, 0, 10)
	consumers := make([]*Consumer, 0, 5)
	// 创建十个消费者
	for i := 0; i < 10; i++ {
		consumers = append(consumers, NewConsumer(i, taskCh))
	}
	// 创建十个生产者
	for i := 0; i < 10; i++ {
		producers = append(producers, NewProducer(i, taskCh))
	}

	tasks := make(chan *ConsumeTask, 100)
	for i := 0; i < 100; i++ {
		t := &ConsumeTask{
			id: i,
			execFunc: func() {
				dura := time.Duration(rand.Intn(3)+1) * time.Second
				time.Sleep(dura)
				fmt.Println("已经睡眠:", dura.String(), "s, 任务", i, "执行中...")
			},
		}
		tasks <- t
	}
	defer close(tasks)

	for _, producer := range producers {
		// 闭包问题
		//go func() {
		//	for t := range tasks {
		//		producer.Produce(t)
		//	}
		//}()

		go func(p *Producer) {
			for t := range tasks {
				p.Produce(t)
			}
		}(producer)
	}

	for _, consumer := range consumers {
		 闭包问题
		//go func() {
		//	consumer.Consume()
		//}()

		go func(c *Consumer) {
			c.Consume()
		}(consumer)
	}

	time.Sleep(time.Second * 10)

}

func NewProducer(id int, ch chan *ConsumeTask) *Producer {
	return &Producer{
		id: id,
		ch: ch,
	}
}

func NewConsumer(id int, ch chan *ConsumeTask) *Consumer {
	return &Consumer{
		id: id,
		ch: ch,
	}
}

func (p *Producer) Produce(task *ConsumeTask) {
	p.ch <- task
}

func (c *Consumer) Consume() {
	for task := range c.ch {
		fmt.Printf("消费者%d,正在消费\n", c.id)
		task.execFunc()
	}
}

结果分析

.....
已经睡眠: 1s s, 任务 26 执行中...
消费者6,正在消费
已经睡眠: 2s s, 任务 27 执行中...
消费者5,正在消费
已经睡眠: 1s s, 任务 30 执行中...
消费者3,正在消费
已经睡眠: 1s s, 任务 32 执行中...
消费者2,正在消费
已经睡眠: 3s s, 任务 22 执行中...
消费者8,正在消费
已经睡眠: 1s s, 任务 35 执行中...
消费者6,正在消费
已经睡眠: 1s s, 任务 37 执行中...
消费者3,正在消费
已经睡眠: 1s s, 任务 36 执行中...
消费者5,正在消费
已经睡眠: 2s s, 任务 29 执行中...
消费者4,正在消费
已经睡眠: 2s s, 任务 31 执行中...
消费者9,正在消费
已经睡眠: 1s s, 任务 39 执行中...
消费者8,正在消费
已经睡眠: 3s s, 任务 28 执行中...
消费者0,正在消费
已经睡眠: 2s s, 任务 38 执行中...
消费者2,正在消费
已经睡眠: 3s s, 任务 33 执行中...
消费者1,正在消费
已经睡眠: 3s s, 任务 34 执行中...
消费者7,正在消费
已经睡眠: 1s s, 任务 44 执行中...
消费者9,正在消费
已经睡眠: 1s s, 任务 41 执行中...
消费者3,正在消费
已经睡眠: 1s s, 任务 42 执行中...
消费者5,正在消费
已经睡眠: 1s s, 任务 45 执行中...
消费者8,正在消费
已经睡眠: 1s s, 任务 46 执行中...
消费者0,正在消费
--- PASS: TestProducerConsumer (10.00s)
PASS

可以看到,10s的时间内,每个任务耗时1-3s下,一共消费了46个任务,相比于顺序消费(3-10)个任务效率高了很多


http://www.kler.cn/a/442697.html

相关文章:

  • 机组存储系统
  • C#补充----反射,特性,迭代器,特殊语法,值类型运用类型。
  • Redis是单线程还是多线程?
  • 非PHP开源内容管理系统(CMS)一览
  • TypeScript Jest 单元测试 搭建
  • 基于DFT与IIR-FIR滤波器的音频分析与噪声处理
  • 电源的分类
  • windows 使用python共享网络给另外一个网卡
  • 谁说C比C++快?
  • 矩阵的基本知识
  • 【ETCD】ETCD 的一致性读(Linearizable Read)流程解析
  • nexus5x安卓root
  • 队列的原理及应用
  • Git安装详解(写吐了,看完不后悔)
  • 9_less教程 --[CSS预处理]
  • 代码生成器
  • 架构实践04-高扩展架构模式
  • node.js的简单示例
  • 0101多级nginx代理websocket配置-nginx-web服务器
  • ElasticSearch系列:利用runtime field实现日期字符串实现日期范围查询
  • 使用Idea自带的git功能进行分支合并
  • 爬虫数据能用于商业吗?
  • linux下的单例安全的线程池实现
  • Android 之永乐大典
  • redis 缓存使用
  • uniapp打包apk允许横屏竖屏内容翻转