Go语言实现生产者-消费者模式

本文介绍使用Go语言的goroutine实现生产者-消费者模型,并通过两个示例演示如何使用单向channel进行并发编程,包括简单的数字生成及斐波那契数列生成。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 之前在学习操作系统的时候,就知道生产者-消费者,但是概念是模模糊糊的,好像是一直没搞明白。
  • 其实很简单嘛,生产者生产,消费者进行消费,就是如此简单。了解了一下go语言的goroutine,感觉实现并发原来可以如此简单,不像之前Java、C++,什么还需要什么线程池啥的。

单向channel最典型的应用是“生产者消费者模型”
所谓“生产者消费者模型”: 某个模块(函数等)负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、协程、线程、进程等)。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。
单单抽象出生产者和消费者,还够不上是生产者/消费者模型。该模式还需要有一个缓冲区处于生产者和消费者之间,作为一个中介。生产者把数据放入缓冲区,而消费者从缓冲区取出数据。

 

package main

import "fmt"

//import "time"

//此通道只能写,不能读
func producer(out chan<- int){
	for i:=0;i<10;i++{
		out<-i*i
	}
	close(out)
}

//此通大道只能读,不能写
func consumer(in <-chan int){
	for num:=range in{
		fmt.Println("num=",num)
	}
}

func main(){
	//创建双向,channel
	ch:=make(chan int)

	//生产者,生产数字,写入channel
	//新开一个协程
	go producer(ch) //channel传参,引用传递

	//消费者,从channel读取内存,打印
	consumer(ch)

简单说明:首先创建一个双向的channel,然后开启一个新的goroutine,把双向通道作为参数传递到producer方法中,同时转成只写通道。子协程开始执行循环,向只写通道中添加数据,这就是生产者。主协程,直接调用consumer方法,该方法将双向通道转成只读通道,通过循环每次从通道中读取数据,这就是消费者。
注意:channel作为参数传递,是引用传递。

实现斐波那契数列

//实现斐波那契数列:1 1 2 3 5 8
package main

import "fmt"

//此时的ch只写,quit只读
func fibonacci(ch chan<-int,quit <-chan bool){
	x,y:=1,1
	for {
		//监听channel数据的流动
		select {
		case ch<-x:
			x,y=y,x+y
		case flag:=<-quit: //没数据时一直处于阻塞状态
			fmt.Println("flag=",flag)
			return   //不能用break,因为只跳出select这一层
		}
	}
}
func main(){
	//创建双向通道,没有缓冲的
	ch:=make(chan int)   //数字通信
	quit:=make(chan bool) //程序是否结束

	//生产者,从channel读取内容
	//新建协程
	go func(){
		for i:=0;i<8;i++{
			num:=<-ch  //只读,没数据时,处于阻塞状态
			fmt.Println("num=",num)  
		}
		//可以停止
		quit<-true  //写
	}()

	//生产者,产生数字,写入channel
	fibonacci(ch,quit)
}

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路上的追梦人

您的鼓励就是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值