Go并发编程的学习代码示例:生产者消费者模型

前言

Go并发编程学习的简单代码示例:生产者消费者模型。


代码仓库


核心概念

并行和并发:

  • 并行:同时运行多个任务。依赖硬件中央处理器(CPU)的数量或CPU的核心数量,CPU或CPU核心的数量越多,能够同时运行的程序/进程越多
  • 并发:宏观上是"同时运行",微观/实际上是在极短的时间内顺序运行多个程序/进程

进程、线程、协程和Go协程(goroutine):

  • 进程:资源分配的基本单位
  • 线程:内核态线程; CPU调度的基本单位
  • 协程:用户态线程;轻量级线程
  • 一个进程可以有多个线程
  • 线程和协程对应关系可以是一对一、一对多和多对多
  • goroutine:Go的协程概念,使用G(Goroutine)-P(Processor)-M(Machine)模型

Go的并发编程:

  • 使用go关键字开启多协程goroutine,而不是多进程和多线程,实现并发

  • 使用管道channal,而不是锁,实现同步互斥和数据通信

可联想进程间通信(IPC)中的管道pipe()、共享内存等方式

  • 使用select{}语句,实现监听输入/输出(I/O)操作

可联想网络编程中的监听文件描述符select()函数
相比于C、C++和其他语言,使用Go实现并发编程的逻辑很简单


main.go(有详细注释)

go 复制代码
package main // 一个工程只有一个main包

// 导入路径
import "fmt" // 用于输出

// 生产者
// 参数:数据管道,单向只写;标志管道,单向只读
func producer(data_channel chan<- int, flag_channel <-chan bool) {
	// 循环处理,接收到消费者标志后才退出循环和函数
	data := 0 //生产者生产的数据

	for {
		// select{}语句监听输入/输出(I/O)操作
		select {
		case data_channel <- data: //有数据写
			data++
		case flag := <-flag_channel: //有标志读
			fmt.Println("生产者读标志:", flag, "结束生产")
			return
		}
	}
}

// 消费者
// 参数:数据管道,单向只读;标志管道,单向只写
func consumer(data_channel <-chan int, flag_channel chan<- bool) {
	// 约定循环5次后,消费者停止消费,向生产者发送停止生产标志
	for i := 0; i < 5; i++ {
		data := <-data_channel //读数据
		fmt.Println("消费者读数据:", data)
	}

	flag_channel <- true //写标志

	return
}

// 一个工程只有一个main()函数,是程序的唯一入口
func main() {
	data_channel := make(chan int, 0)
	// 数据管道,生产者向消费者传输数据
	// 传输int类型数据,0:无缓冲,双向
	flag_channel := make(chan bool, 0)
	// 标志管道,消费者向生产者传输标志,消费者不再消费,让生产者停止生产
	// 传输bool类型数据,0:无缓冲,双向

	go consumer(data_channel, flag_channel) //go关键字开启goroutine处理消费者任务

	producer(data_channel, flag_channel) // main()中是主goroutine,处理生产者任务
}

结果

powershell 复制代码
PS C:\Users\DSHH\Desktop\go_test> go run main.go
消费者读数据: 0
消费者读数据: 1
消费者读数据: 2
消费者读数据: 3
消费者读数据: 4
生产者读标志: true 结束生产
PS C:\Users\DSHH\Desktop\go_test> 

总结

Go并发编程的学习代码示例:生产者消费者模型。


参考资料


作者的话

  • 感谢参考资料的作者/博主
  • 作者:夜悊
  • 版权所有,转载请注明出处,谢谢~
  • 如果文章对你有帮助,请点个赞或加个粉丝吧,你的支持就是作者的动力~
  • 文章在描述时有疑惑的地方,请留言,定会一一耐心讨论、解答
  • 文章在认识上有错误的地方, 敬请批评指正
  • 望读者们都能有所收获

相关推荐
JWASX15 小时前
Java 转 go 学习 - 项目管理
go
喵个咪18 小时前
Go 写业务,Rust 扛底盘:一套可落地的混合架构
后端·rust·go
EatFan19 小时前
Go语言全栈实战:基于 Gin + Vue + JWT + RBAC 从零搭建前后端分离权限管理系统
vue.js·golang·go·vue·gin·jwt·rbac
ZealSinger19 小时前
Go slog生产落地LevelVar与共存
开发语言·后端·golang·go
福兮说21 小时前
Go encoding/json 的八个默认行为,以及 Go 1.25 的 json/v2 改了哪几个(附实测输出)
go
合橱瑰21 小时前
踩坑实录:包是好的,代码却报错?一次“数字ID”引发的插件启动血案
架构·go
NetX行者1 天前
五大主流语言:Go、Python、Rust、Java、C# 的比较
go
Thinker QAQ2 天前
并发编程(六):Atomic 的实现——从 Runtime 到 CPU
java·go·cas·并发编程·atomic·cpython
喵个咪2 天前
GoWind Admin|风行 — 开箱即用的企业级全栈中后台框架:多租户与行级数据隔离
后端·go
喵个咪2 天前
GoWind Admin|风行 — 开箱即用的企业级全栈中后台框架:脚本系统实战
javascript·后端·go