【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)个任务效率高了很多

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值