Go实现生产者消费者模型

Go实现生产者消费者模型

基于同步锁实现

import (
	"fmt"
	"sync"
)
var (
	productCount = 5
	mutex sync.Mutex
	cond = sync.NewCond(&mutex)
)
type producer struct {

}
func (r *producer) produce() {
	for {
		cond.L.Lock()
		if productCount < 10 {
			productCount++
			fmt.Printf("生产者生产了一个产品,当前存量%d\n", productCount)
		} else {
			fmt.Printf("仓库满了,当前容量%d\n", productCount)
			cond.Wait()
		}
		cond.L.Unlock()
		cond.Broadcast()
	}
}
func (r *consumer) consumer() {
	for {
		cond.L.Lock()
		if productCount > 0 {
			productCount--
			fmt.Printf("消费者消费了一个产品,当前存量%d\n", productCount)
		} else {
			fmt.Printf("仓库空了,当前存量%d\n", productCount)
			cond.Wait()
		}
		cond.L.Unlock()
		cond.Broadcast()
	}
}
type consumer struct {

}
func main() {
	var p = producer{}
	var c = consumer{}
	go p.produce()
	go c.consumer()
}

在这里插入图片描述
然而实际什么都没有输出,这是因为生产者消费者执行方法时主线程已经结束了,给主线程加个时延

func main() {
	var p = producer{}
	var c = consumer{}
	go p.produce()
	go c.consumer()
	time.Sleep(time.Microsecond * 10)
}

在这里插入图片描述

基于通道实现

基于通道实现的这种方式需要注意避免从空通道中取数,否则就会出现死锁

var countChan chan int

type producer struct {
}

func (r *producer) produce() {
	for i := 0; i < 10; i++ {
		count := <-countChan
		if count < 10 {
			count++
			fmt.Printf("生产者生产了一个产品,当前存量%d\n", count)
		} else {
			fmt.Printf("仓库满了,当前容量%d\n", count)
		}
		countChan <- count
		var t = rand.Intn(100)
		time.Sleep(time.Duration(t))
	}
}

func (r *consumer) consumer() {
	for i := 0; i < 10; i++ {
		count := <-countChan
		if count > 0 {
			count--
			fmt.Printf("消费者消费了一个产品,当前存量%d\n", count)
		} else {
			fmt.Printf("仓库空了,当前存量%d\n", count)
		}
		countChan <- count
		var t = rand.Intn(100)
		time.Sleep(time.Duration(t))
	}
}

type consumer struct {
}

func main() {
	countChan = make(chan int, 1)
	countChan <- 0
	var p = producer{}
	var c = consumer{}
	go p.produce()
	go c.consumer()
	time.Sleep(1000)
}

基于select解决通道阻塞问题

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

var countChan chan int

type producer struct {
}

func (r *producer) produce() {
	for i := 0; i < 10; i++ {
		select {
		case count := <-countChan:
			if count < 10 {
				count++
				fmt.Printf("生产者生产了一个产品,当前存量%d\n", count)
			} else {
				fmt.Printf("仓库满了,当前容量%d\n", count)
			}
			countChan <- count
			var t = rand.Intn(100)
			time.Sleep(time.Duration(t))
		default:
			fmt.Println("初始化产品池")
			countChan <- 0
		}
	}
}

func (r *consumer) consumer() {
	for i := 0; i < 10; i++ {
		select {
		case count := <-countChan:
			if count > 0 {
				count--
				fmt.Printf("消费者消费了一个产品,当前存量%d\n", count)
			} else {
				fmt.Printf("仓库空了,当前存量%d\n", count)
			}
			countChan <- count
			var t = rand.Intn(100)
			time.Sleep(time.Duration(t))
		default:
			fmt.Println("初始化产品池")
			countChan <- 0
		}

	}
}

type consumer struct {
}

func main() {
	countChan = make(chan int, 1)
	var p = producer{}
	var c = consumer{}
	go p.produce()
	go c.consumer()
	time.Sleep(10000)
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值