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

使用Golang实现开发中常用的【并发设计模式】

使用Golang实现开发中常用的【并发设计模式】

设计模式是解决常见问题的模板,可以帮助我们提升思维能力,编写更高效、可维护性更强的代码

屏障模式

未来模式

管道模式

协程池模式

发布订阅模式

下面是使用 Go 语言实现屏障模式、未来模式、管道模式、协程池模式和发布订阅模式的示例代码。

1. 屏障模式

屏障模式(Barrier Pattern)用于同步多个 goroutine,在所有 goroutine 都到达某个点之前,任何 goroutine 都不能继续执行。

package mainimport ("fmt""sync"
)func main() {const numWorkers = 5var wg sync.WaitGroupwg.Add(numWorkers)// 创建一个 Barrierbarrier := make(chan struct{}, numWorkers)for i := 0; i < numWorkers; i++ {go func(id int) {defer wg.Done()// 模拟工作fmt.Printf("Worker %d is working...\n", id)// 到达屏障点barrier <- struct{}{}// 等待所有 goroutine 到达屏障点<-barrier// 继续工作fmt.Printf("Worker %d continues after barrier.\n", id)}(i)}wg.Wait()close(barrier)
}

2. 未来模式

未来模式(Future Pattern)用于异步获取结果,通常用于长时间运行的任务。

package mainimport ("fmt""time"
)type Future interface {Get() (string, error)
}type futureImpl struct {resultChan chan stringerrChan    chan error
}func NewFuture() Future {f := &futureImpl{resultChan: make(chan string, 1),errChan:    make(chan error, 1),}go f.run()return f
}func (f *futureImpl) run() {// 模拟长时间运行的任务time.Sleep(2 * time.Second)select {case f.resultChan <- "Result":case f.errChan <- nil:}
}func (f *futureImpl) Get() (string, error) {select {case result := <-f.resultChan:return result, nilcase err := <-f.errChan:return "", err}
}func main() {future := NewFuture()fmt.Println("Doing other work...")result, err := future.Get()if err != nil {fmt.Println("Error:", err)} else {fmt.Println("Result:", result)}
}

3. 管道模式

管道模式(Pipeline Pattern)用于将多个 goroutine 串联起来,形成一个数据处理流水线。

package mainimport ("fmt""time"
)func produce(in chan<- int) {for i := 0; i < 10; i++ {in <- itime.Sleep(100 * time.Millisecond)}close(in)
}func process(out <-chan int, in chan<- int) {for v := range out {v *= 2in <- v}close(in)
}func consume(in <-chan int) {for v := range in {fmt.Println("Consumed:", v)}
}func main() {ch1 := make(chan int)ch2 := make(chan int)go produce(ch1)go process(ch1, ch2)go consume(ch2)time.Sleep(2 * time.Second)
}

4. 协程池模式

协程池模式(Coroutine Pool Pattern)用于管理和重用一组固定数量的 goroutine。

package mainimport ("fmt""sync""time"
)type Task func(int)type GoroutinePool struct {size    inttasks   chan Taskwg      sync.WaitGroupstop    boolstopCh  chan struct{}doneCh  chan struct{}
}func NewGoroutinePool(size int) *GoroutinePool {return &GoroutinePool{size:   size,tasks:  make(chan Task),stopCh: make(chan struct{}),doneCh: make(chan struct{}),}
}func (p *GoroutinePool) Start() {for i := 0; i < p.size; i++ {p.wg.Add(1)go p.worker(i)}
}func (p *GoroutinePool) worker(id int) {defer p.wg.Done()for {select {case task := <-p.tasks:task(id)case <-p.stopCh:p.doneCh <- struct{}{}return}}
}func (p *GoroutinePool) Submit(task Task) {p.tasks <- task
}func (p *GoroutinePool) Stop() {p.stop = trueclose(p.stopCh)p.wg.Wait()close(p.doneCh)
}func main() {pool := NewGoroutinePool(5)pool.Start()for i := 0; i < 20; i++ {task := func(id int) {fmt.Printf("Task %d handled by worker %d\n", i, id)time.Sleep(100 * time.Millisecond)}pool.Submit(task)}time.Sleep(1 * time.Second)pool.Stop()
}

5. 发布订阅模式

发布订阅模式(Publish-Subscribe Pattern)用于解耦消息的发送者和接收者。

package mainimport ("fmt""sync"
)type Event stringtype Subscriber func(Event)type Publisher struct {mu         sync.Mutexsubscribers map[Subscriber]struct{}
}func NewPublisher() *Publisher {return &Publisher{subscribers: make(map[Subscriber]struct{}),}
}func (p *Publisher) Subscribe(subscriber Subscriber) {p.mu.Lock()defer p.mu.Unlock()p.subscribers[subscriber] = struct{}{}
}func (p *Publisher) Unsubscribe(subscriber Subscriber) {p.mu.Lock()defer p.mu.Unlock()delete(p.subscribers, subscriber)
}func (p *Publisher) Publish(event Event) {p.mu.Lock()defer p.mu.Unlock()for sub := range p.subscribers {go sub(event)}
}func main() {pub := NewPublisher()subscriber1 := func(event Event) {fmt.Printf("Subscriber 1 received: %s\n", event)}subscriber2 := func(event Event) {fmt.Printf("Subscriber 2 received: %s\n", event)}pub.Subscribe(subscriber1)pub.Subscribe(subscriber2)pub.Publish("Event 1")pub.Publish("Event 2")pub.Unsubscribe(subscriber1)pub.Publish("Event 3")
}

总结

  1. 屏障模式:使用通道和 sync.WaitGroup 同步多个 goroutine。
  2. 未来模式:使用通道异步获取任务结果。
  3. 管道模式:使用通道连接多个 goroutine 形成数据处理流水线。
  4. 协程池模式:管理一组固定数量的 goroutine,重用这些 goroutine 处理任务。
  5. 发布订阅模式:解耦消息的发送者和接收者,使用通道广播消息。

相关文章:

使用Golang实现开发中常用的【并发设计模式】

使用Golang实现开发中常用的【并发设计模式】 设计模式是解决常见问题的模板&#xff0c;可以帮助我们提升思维能力&#xff0c;编写更高效、可维护性更强的代码 屏障模式 未来模式 管道模式 协程池模式 发布订阅模式 下面是使用 Go 语言实现屏障模式、未来模式、管道模式…...

基于Zynq FPGA对雷龙SD NAND的性能测试评估

文章目录 一、SD NAND特征1.1 SD卡简介1.2 SD卡Block图 二、SD卡样片三、Zynq测试平台搭建3.1 测试流程3.2 SOC搭建 四、软件搭建五、测试结果六、总结 一、SD NAND特征 1.1 SD卡简介 雷龙的SD NAND系列有多种型号&#xff0c;本次测试使用的是CSNP4GCR01-AMW和CSNP32GCR01-A…...

4.WebSocket 配置与Nginx 的完美结合

序言 在现代 web 应用中&#xff0c;WebSocket 作为一种全双工通信协议&#xff0c;为实时数据传输提供了强大的支持。若要确保 WebSocket 在生产环境中的稳定性和性能&#xff0c;使用 Nginx 作为反向代理服务器是一个明智的选择。本篇文章将带你了解如何在 Nginx 中配置 Web…...

Docker:镜像构建 DockerFile

Docker&#xff1a;镜像构建 DockerFile 镜像构建docker build DockerfileFROMCOPYENVWORKDIRADDRUNCMDENTRYPOINTUSERARGVOLUME 镜像构建 在Docker官方提供的镜像中&#xff0c;大部分都是基础镜像&#xff0c;他们只提供某个简单的功能&#xff0c;如果想要一个功能更加丰富…...

浮动路由:实现出口线路的负载均衡冗余备份。

浮动路由 Tip&#xff1a;浮动路由指在多条默认路由基础上加入优先级参数&#xff0c;实现出口线路冗余备份。 ip routing-table //查看路由表命令 路由优先级参数&#xff1a;越小越优 本次实验测试两条默认路由&#xff0c;其中一条默认路由添加优先级参数&#xff0c;设置…...

二叉树的遍历和线索二叉树

二叉树遍历 二叉树结点的定义 typedef struct BiNode{Elemtype data;struct BiNode* lchild, *rchild; }BiNode, *BiTree; 先序 递归算法 void PreOrder1(BiTree T){if(T!NULL){visit(T);PreOrder(T->lchild);PreOrder(T->rchild);} } 非递归算法&#xff08;栈实现…...

SpringBoot3 集成Junit4

目录 1. 确保项目中包含JUnit 4依赖添加JUnit 4依赖 2. 配置Spring Boot使用JUnit 4在测试类中使用RunWith注解 3. 编写测试代码4、总结 【扩展】RunWith(SpringRunner.class) 中SpringRunner的作用1. **加载 Spring 应用上下文&#xff08;ApplicationContext&#xff09;**2.…...

Scala的set的添加删减和查询

添加&#xff1a;最好用于不可变数组&#xff0c;因为它会产生新数组&#xff0c;而不是在原数组上进行修改。 在尾部添加元素 可变数组 删减&#xff1a;按元素值删除元素 - 查询&#xff1a;查询元素是否存在.contains package Test //Set //特点&#xff1a;元素是唯…...

基于微信小程序的移动学习平台的设计与实现+ssm(lw+演示+源码+运行)

摘 要 由于APP软件在开发以及运营上面所需成本较高&#xff0c;而用户手机需要安装各种APP软件&#xff0c;因此占用用户过多的手机存储空间&#xff0c;导致用户手机运行缓慢&#xff0c;体验度比较差&#xff0c;进而导致用户会卸载非必要的APP&#xff0c;倒逼管理者必须改…...

【spark面试题】RDD和DataFrame以及DataSet有什么异同

RDD&#xff08;Resilient Distributed Dataset&#xff09;&#xff1a; 概念&#xff1a;可理解为分布式的列表。它的每个元素代表数据的一行&#xff0c;具有支持泛型这一显著特点。这种泛型支持让开发人员能够处理各种类型的数据&#xff0c;具有很强的灵活性。例如&#…...

[Python]关于Tensorflow+Keras+h5py+numpy一些骚操作备忘

起因&#xff1a;要在Anaconda使用Tensorflow和Keras框架 这里提前小结一下&#xff1a; 1&#xff0c;一定要注意Python、Tensorflow、Keras不同版本的对应关系。 2&#xff0c;交叉用conda install 和pip install安装依赖库可能容易出现问题&#xff0c;在Anaconda虚拟环境…...

深度学习:Transformer 详解

Transformer 详解 对于Transformer模型的详细解释&#xff0c;可以更深入地探讨其各个组成部分、工作原理、以及在自然语言处理任务中的应用方法。以下是对Transformer模型的一个更全面和详细的解释&#xff0c;包括其架构细节和关键技术&#xff1a; 1. 基本架构 Transform…...

jmeter 性能测试步骤是什么?

JMeter是一款流行的开源性能测试工具&#xff0c;用于测试各种服务器和网络应用的性能。在进行JMeter性能测试时&#xff0c;通常需要遵循以下步骤&#xff1a; 确定测试目标&#xff1a;首先&#xff0c;明确性能测试的目标。这可以是测试一个网站的负载能力、测试一个API的响…...

前端入门一之JS最基础、最基础语法

前言 JS是前端三件套之一&#xff0c;也是核心&#xff0c;本人将会更新JS基础、JS对象、DOM、BOM、ES6等知识点&#xff1b;这篇文章是本人大一学习前端的笔记&#xff1b;欢迎点赞 收藏 关注&#xff0c;本人将会持续更新。 文章目录 初体验输入输出语句变量和常量常量变量…...

解决Swp交换空间被占满问题

解决ubuntu交换空间被占满问题 step1: cat /proc/sys/vm/swappiness 60 step2: sudo sysctl vm.swappiness10 #临时修改 step3: sudo sh -c “echo “vm.swappiness10” >> /etc/sysctl.conf” step4: sysctl -p #生效...

草地景观中的土地覆被变化:将增强型大地遥感卫星数据组成、LandTrendr 和谷歌地球引擎中的机器学习分类与 MLP-ANN 场景预测相结合

目录 简介 方法 结论 代码1:影像集合 代码2: 随机森林和svm分类 结果 简介 了解草原生境在空间和时间上的动态对于评估保护措施的有效性和制定可持续管理方法至关重要,特别是在自然 2000 网络和欧洲生物多样性战略范围内。 根据遥感数据绘制的土地覆盖图对于了解植被…...

【c++语言程序设计】字符串与浅层复制(深拷贝与浅拷贝)

字符串常量是用一对双引号括起来的字符序列&#xff0c;例如&#xff0c;"abcd" " China"" This is a string." 都是字符串常量。它在内存中的存放形式是&#xff0c;按串中字符的排列次序顺序存放&#xff0c;每个字符占1字节&#xff0c;并在末…...

《TCP/IP网络编程》学习笔记 | Chapter 4:基于TCP的服务器端/客户端(1)

《TCP/IP网络编程》学习笔记 | Chapter 4&#xff1a;基于TCP的服务器端/客户端&#xff08;1&#xff09; 《TCP/IP网络编程》学习笔记 | Chapter 4&#xff1a;基于TCP的服务器端/客户端&#xff08;1&#xff09;理解TCP和UDPTCP/IP协议栈TCP/IP协议的诞生背景链路层网络层T…...

深入解析gdb -p 与gdb attach 的区别与使用场景

摘要&#xff1a;本文将详细对比gdb -p 与gdb attach 这两个命令的使用方法、场景及优缺点&#xff0c;帮助读者更好地理解并运用这两个调试工具。 一、引言 在Linux系统中&#xff0c;GDB&#xff08;GNU Debugger&#xff09;是一款功能强大的调试工具&#xff0c;广泛应用…...

C语言 | Leetcode C语言题解之第542题01矩阵

题目&#xff1a; 题解&#xff1a; /*** Return an array of arrays of size *returnSize.* The sizes of the arrays are returned as *returnColumnSizes array.* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().*/ type…...

Unity 2D开发第一课:建立空间直觉与项目根基

1. 为什么“Unity 2D 游戏开发教程&#xff08;一&#xff09;”不是从“新建项目”开始讲起 很多人点开标题叫“Unity 2D 游戏开发教程&#xff08;一&#xff09;”的视频或文章&#xff0c;第一帧就看到编辑器界面、鼠标点“New Project”、输入项目名、选模板——然后心里一…...

TBP-9000-R0AE无风扇工控机:6网口4PoE+,严苛工业环境下的边缘计算与机器视觉平台

1. 项目概述&#xff1a;一台为严苛环境而生的工业“大脑”在工业自动化、机器视觉、轨道交通这些领域里&#xff0c;选一台靠谱的工控机&#xff0c;远比在办公室挑台电脑复杂得多。它不仅要算力够用&#xff0c;更得扛得住震动、耐得了高低温、接得了五花八门的工业设备&…...

液压液水解安定性检测:核心原理与全行业应用场景解析

液压系统是各类工业、工程、交通设备的动力核心&#xff0c;而液压液作为系统的工作介质&#xff0c;其性能稳定性直接决定设备的运行精度、故障率以及使用寿命。在复杂工况中&#xff0c;水分侵入是导致液压液失效的核心诱因之一&#xff0c;油液遇水发生水解反应后&#xff0…...

CNN与量化神经网络在高能物理实时触发系统中的应用

1. WOMBAT架构概述&#xff1a;当CNN遇上高能物理在大型强子对撞机&#xff08;LHC&#xff09;的紧凑型μ子螺线管&#xff08;CMS&#xff09;实验中&#xff0c;每秒产生约4000万次质子碰撞事件。传统触发系统需要处理海量数据流&#xff0c;而WOMBAT架构的创新之处在于将卷…...

从零手写K-Means聚类算法:理解初始化、分配与收敛的底层原理

1. 项目概述&#xff1a;从零手写K-Means&#xff0c;不只是调包&#xff0c;而是真正理解聚类的“心跳”你有没有过这种感觉&#xff1a;调用sklearn.cluster.KMeans跑完一个聚类任务&#xff0c;结果图一出、轮廓系数一算&#xff0c;好像就结束了&#xff1f;但当同事问起“…...

Bpmn Process Designer性能优化指南:大型流程图的渲染与交互优化

Bpmn Process Designer性能优化指南&#xff1a;大型流程图的渲染与交互优化 【免费下载链接】bpmn-process-designer bpmn-js 工具库 项目地址: https://gitcode.com/gh_mirrors/bp/bpmn-process-designer Bpmn Process Designer是一款基于bpmn-js的强大流程设计器工具…...

2021年5月AI工程化三大关键突破:Deformable DETR、REALM与WB Model Registry

1. 项目概述&#xff1a;这不是一份榜单&#xff0c;而是一份2021年5月AI领域真实水位的切片报告“The AI Monthly Top 3 — May 2021”这个标题乍看像一份轻量级资讯简报&#xff0c;但在我连续追踪AI领域动态超过十年、亲手部署过从BERT-base到GPT-3早期API调用、从YOLOv3训练…...

软考中级《嵌入式系统设计师》全套备考资料(真题 + 教材 + 笔记)

大家好&#xff0c;今天给大家分享一份软考中级「嵌入式系统设计师」的完整备考资料包&#xff0c;从教材、真题到高频笔记全配齐&#xff0c;帮你省去整理资料的时间&#xff0c;直接进入高效备考状态&#xff01; &#x1f4c1; 资料清单 这套资料覆盖了嵌入式系统设计师备考…...

10个Elog实用技巧:让你的博客管理效率翻倍

10个Elog实用技巧&#xff1a;让你的博客管理效率翻倍 【免费下载链接】elog Markdown 批量导出工具、开放式跨平台博客解决方案&#xff0c;随意组合写作平台(语雀/Notion/FlowUs/飞书/我来Wolai)和博客平台(Hexo/Vitepress/Halo/Confluence/WordPress等) 项目地址: https:/…...

为什么你需要英雄联盟Akari助手:3个步骤提升游戏效率的完整指南

为什么你需要英雄联盟Akari助手&#xff1a;3个步骤提升游戏效率的完整指南 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power &#x1f680;. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 还在为英雄联盟中繁…...