go语言进阶之并发模式

并发模式

并发模式是指在程序设计中同时处理多个任务或进程的方式,以提高效率和响应性

for select循环模式

for select循环模式通常用于处理并发操作,尤其是在需要等待多个通道时。

select的执行过程主要是以下几步

  1. 阻塞等待,直到其中一个通道可用
  2. 执行case,当一个通道准备好了,select将会执行对应的case
  3. 随机选择,如果多个通道可用,go会随机选择一个case执行
  4. 循环执行,在for循环中,select可以持续运行,监听多个通道

比如:

package main  import (  "fmt"  "time")  func main() {  ch1 := make(chan string)  ch2 := make(chan string)  go func() {  time.Sleep(1 * time.Second)  ch1 <- "来自ch1的消息"  }()  go func() {  time.Sleep(1 * time.Second)  ch2 <- "来自ch2的消息"  }()  for {  select {  case msg1 := <-ch1:  fmt.Println("接收到", msg1)  case msg2 := <-ch2:  fmt.Println("接收到", msg2)  case <-time.After(3 * time.Second):  fmt.Println("超时")  return  }  }  
}

可以看到所有通道都可以输出。

select timeout模式

在go语言中使用数据库和网络请求时,一般都会设置查询超时,从而防止操作长时间挂起

package main  import (  "context"  "database/sql"    "fmt"    "log"    "time"  _ "github.com/lib/pq" // PostgreSQL driver  
)  func main() {  // 连接到数据库  db, err := sql.Open("postgres", "user=username dbname=mydb sslmode=disable")  if err != nil {  log.Fatal(err)  }  defer db.Close()  // 设置查询超时为5秒  ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)  defer cancel() // 确保在操作完成后调用cancel  // 执行查询  var result string  err = db.QueryRowContext(ctx, "SELECT name FROM users WHERE id = \$1", 1).Scan(&result)  if err != nil {  if err == context.DeadlineExceeded {  fmt.Println("查询超时")  } else {  log.Fatal(err)  }  } else {  fmt.Println("查询结果:", result)  }  
}

Pipeline模式(流水线模式)

流水线模式模拟的就是现实的流水线生产。主要就是通过一道道工序组装而成,每一道工序只负责自己的事情,这种模式就是流水线模式。

package mainimport ("fmt""sync"
)// 生产者,生成数据
func producer(out chan<- int, wg *sync.WaitGroup) {defer wg.Done()for i := 0; i < 10; i++ {out <- i}close(out)
}// 处理阶段,处理数据
func worker(in <-chan int, out chan<- int, wg *sync.WaitGroup) {defer wg.Done()for n := range in {out <- n * 2 // 示例处理:将数字乘以 2}close(out)
}// 消费者,接收处理后的数据
func consumer(in <-chan int, wg *sync.WaitGroup) {defer wg.Done()for n := range in {fmt.Println(n) // 输出处理后的结果}
}func main() {var wg sync.WaitGroup// 创建用于连接各个阶段的 channelpipeline1 := make(chan int)pipeline2 := make(chan int)wg.Add(1)go producer(pipeline1, &wg)wg.Add(1)go worker(pipeline1, pipeline2, &wg)wg.Add(1)go consumer(pipeline2, &wg)// 等待所有 goroutine 完成wg.Wait()
}

这一段代码主要通过流水线模式来实现了0到9的数据乘2并打印,其中每个函数都是独立完成一个步骤并拼接起来的。

可以通过代码发现流水线模式的特点

  1. 在使用流水线模式时,每道工序都通过channel将数据传递到下一个工序
  2. 每一个工序一般都会对应一个函数
  3. 最终要有个main函数类似函数将这些工序串起来,这样就可以形成完整的数据流

扇出和扇入模式

扇入模式和扇出模式是由于流水线模式的运行速度不佳而进行改造的模式。

其中原理为增加流水线某个速度低下的步骤,让其同时运行多个步骤,再汇总到下一步骤中。

扇出(Fan-out)

扇出是指将一个输入流的数据分发到多个处理单元(goroutines)。这种模式可以用来提高处理能力,允许多个并发执行的 goroutine 同时处理数据。

package mainimport ("fmt""sync"
)// 处理函数
func worker(id int, jobs <-chan int, wg *sync.WaitGroup) {defer wg.Done()for job := range jobs {fmt.Printf("Worker %d processing job %d\n", id, job)}
}func main() {const numWorkers = 3jobs := make(chan int, 10)var wg sync.WaitGroup// 启动多个 workerfor i := 1; i <= numWorkers; i++ {wg.Add(1)go worker(i, jobs, &wg)}// 发送任务for j := 1; j <= 10; j++ {jobs <- j}close(jobs) // 关闭 jobs channel 以结束 workerwg.Wait() // 等待所有 worker 完成
}

扇入(Fan-in)

扇入是指将多个输入流的数据汇聚到一个处理单元。它可以用来合并多个 goroutine 的结果到一个 channel,通常在需要整合多个处理结果时使用。

package mainimport ("fmt""sync"
)// 生成任务的函数
func generate(id int, jobs chan<- int, wg *sync.WaitGroup) {defer wg.Done()for j := 0; j < 3; j++ {jobs <- j + id*3 // 生成不同的任务}
}// 执行任务的函数
func worker(jobs <-chan int, wg *sync.WaitGroup) {defer wg.Done()for job := range jobs {fmt.Printf("Processing job %d\n", job)}
}func main() {const numGenerators = 3jobs := make(chan int, 10)var wg sync.WaitGroup// 启动生成器for i := 0; i < numGenerators; i++ {wg.Add(1)go generate(i, jobs, &wg)}// 启动一个 worker 处理所有任务wg.Add(1)go worker(jobs, &wg)// 等待所有生成器完成wg.Wait()close(jobs) // 关闭 jobs channel// 等待 worker 完成wg.Wait()
}

Future模式

Future模式是一个处理异步操作的编程模式,它与pipeline模式中工序必须要一个个运行不太一样,

Future模式允许在执行耗时操作是,不必等待操作完成,可以同时进行多个步骤,从而提高程序的效率和响应性。

其基本概念有:

  1. 异步执行:通过goroutines来异步执行任务
  2. 结果封装:使用通道来传递任务的结果
  3. 错误处理:同时处理异步操作可能出现的错误

总的来说,这个模式就是可以同时操作多个不同步骤,当所有操作结束时再进行返回。

package main  import (  "fmt"  "time")  type Future struct {  result interface{}  err    error  
}  func AsyncTask() Future {  ch := make(chan Future)  go func() {  time.Sleep(2 * time.Second)  ch <- Future{result: "Task completed", err: nil}  }()  return <-ch  
}  func main() {  future := AsyncTask()  if future.err != nil {  fmt.Println("Error:", future.err)  } else {  fmt.Println(future.result)  }  
}

其最大的特点就是返回结果,所以在未来获取这个结果的操作必须是一个阻塞的操作,要一直等待获取结果为止。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/13849.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

清华、国科大、智谱团队提出LongReward:利用AI反馈改进长文本大语言模型

长文本&#xff08;Long-context&#xff09;大模型性能的优劣&#xff0c;在很大程度上取决于其能否全面理解长上下文场景下的复杂信息。 然而&#xff0c;现有的合成有监督微调&#xff08;SFT&#xff09;数据由于缺少人类核验&#xff0c;往往会影响长文本大模型的性能&am…

2024 年 10 款替代 Postman 的工具,有免费有开源

10 款替代 Postman 的工具&#xff0c;有免费有开源&#xff1a; 工具名称支持的系统是否免费是否开源ApifoxWindows, macOS, Linux免费否Yapi无限制是是InsomniaWindows, macOS, Linux免费版付费版是Hoppscotch浏览器是是SoapUIWindows, macOS, Linux免费版付费版是Katalon S…

IDEA报包不存在,但实际存在

IDEA版本2024.2.1 现象 在IDEA里启动运行项目&#xff0c;报某个类有问题&#xff0c;引入的包不存在。 点击这个引入的包&#xff0c;可以看到它在左侧外部库里存在。 试过的无效方法 双击ctrl&#xff0c;在弹出框中mvn idea:idea在文件里&#xff0c;清空缓存并重启在右…

从词向量到多模态嵌入:大型语言模型的技术、应用及未来方向

索引词—大型语言模型、词嵌入、上下文嵌入、多模态表示、自然语言处理 摘要—词嵌入和语言模型通过将语言元素表示在连续向量空间中&#xff0c;彻底改变了自然语言处理&#xff08;NLP&#xff09;。本综述回顾了分布假设和上下文相似性等基础概念&#xff0c;追溯了从稀疏表…

超越传统:探索ONLYOFFICE的革命性办公新纪元

目录 &#x1f341;引言 &#x1f341;一、ONLYOFFICE产品简介 &#xff08;一&#xff09;、介绍 &#xff08;二&#xff09;、基本功能简介 &#x1f341;二、核心功能具体介绍 1、编辑操作 2、文本与段落&#xff1a; 3、样式与图形&#xff1a; 4、表格与图表&…

【GESP】C++一级真题(202406)luogu-B4001,立方数

2024年6月GESP一级真题。循环类问题。 题目题解详见&#xff1a;【GESP】C一级真题(202406)luogu-B4001&#xff0c;立方数 | OneCoder https://www.coderli.com/gesp-1-luogu-b4001/https://www.coderli.com/gesp-1-luogu-b4001/ C GESP专项交流频道&#xff1a;GESP学习交…

SAP 创建物料主数据报错:估价范围3010还没有生产式的物料帐簿

通过接口创建物料主数据&#xff08;模拟MM01&#xff09;&#xff0c;报错如图&#xff1a; 处理方案1&#xff1a;&#xff08;我的不行&#xff0c;提示已经是生产的&#xff09; 将评估范围的物料分类账设置为生产 事务码: CKMSTART - 物料分类帐的生产开始 处理方案2&a…

Python | Leetcode Python题解之第560题和为K的子数组

题目&#xff1a; 题解&#xff1a; class Solution:def subarraySum(self, nums: List[int], k: int) -> int:dic{0:1}sums,res0,0for num in nums:sumsnumresdic.get(sums-k,0)dic[sums]dic.get(sums,0)1return res

sql注入之二次注入(sqlilabs-less24)

二阶注入&#xff08;Second-Order Injection&#xff09;是一种特殊的 SQL 注入攻击&#xff0c;通常发生在用户输入的数据首先被存储在数据库中&#xff0c;然后在后续的操作中被使用时&#xff0c;触发了注入漏洞。与传统的 SQL 注入&#xff08;直接注入&#xff09;不同&a…

AOA-LSTM多输入回归预测|算术优化算法-长短期神经网络|Matlab

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、方法原理介绍&#xff1a; 四、完整代码数据下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平…

认知战认知作战:郑成功收复台湾的认知作战分析与策略

认知战认知作战&#xff1a;郑成功收复台湾的认知作战分析与策略 认知战认知作战&#xff1a;郑成功收复台湾的认知作战分析与策略 关键词&#xff1a;认知作战,新质生产力,人类命运共同体,认知战,认知域,认知战研究中心,认知战争,认知战战术,认知战战略,认知域作战研究,认知…

单细胞技术加持,扩增子测序重回高大上| 一区微生物多组学研究新思路!

俗称“万金油”的扩增子技术已经再难发出好文章了&#xff1f;实则不然!关联高端霸气上档次的单细胞转录组技术&#xff0c;扩增子研究依旧可以焕发新生机&#xff0c;重回高大上。 近日&#xff0c;檀国大学在《communications biology》上最新发表的文章打破了传统微生物组分…

遗传算法与深度学习实战(23)——利用遗传算法优化深度学习模型

遗传算法与深度学习实战&#xff08;23&#xff09;——利用遗传算法优化深度学习模型 0. 前言1. 神经进化2. 使用遗传算法作为深度学习优化器小结系列链接 0. 前言 神经进化涵盖了所有用于改进深度学习的进化算法。更具体地说&#xff0c;神经进化用来定义应用于深度学习的特…

Hbase入门

目录 Hbase逻辑结构 一、基础知识 1. Hbase逻辑结构 行键(Rowkey)&#xff1a;唯一标识一行数据&#xff0c;按照字典序(row_key1 < row_key11 < rowkey2)排列.列Col&#xff1a;数据记录的一条属性列族&#xff1a;将多列划分为一类&#xff0c;视为一个列族。例如上图…

三维模型-管道-建模规范

一、阀门模型处理 Max中的阀门模型,备份之前可拆分的阀门模型。 将需要选择的阀门,合并(不打组)成一个模型。 材质在不同模型上,按照需求分好不同的材质 例如:阀门、管道,需要分成不同的材质和相对应的不同模型。 二、管道模型处理 1) 普通管道 默认展开UV ;2) 流…

golang go语言 组建微服务架构详解 - 代码基于开源框架grpc+nacos服务管理配置平台

整体介绍&#xff1a; 本文主要介绍如何用go语言 来组建微服务的框架&#xff0c;grpc服务管理 示例框架 代码由grpcnacos go sdk 组成。 grpc负责将调用序列化并传递到远端&#xff0c;nacos负责服务发现和服务管理。 grpc和nacos都是开源产品。代码复制下来就能跑。 微服…

open3d

open3d open3d用于 3D 数据处理的现代库。 简介 Open3D 是一个开源库&#xff0c;支持快速开发处理 3D 数据的软件。Open3D 前端公开了一组精心挑选的 C 和 Python 数据结构和算法。后端经过高度优化&#xff0c;并设置为并行化。Open3D 是从零开始开发的&#xff0c;具有一更…

一个轻量级RAG文本切块项目Chonkie

**Chonkie&#xff1a;**实用的RAG分块库&#xff0c;轻量级、速度快&#xff0c;可随时对文本进行分块 支持的方法 Chonkie 提供了多个分块器&#xff0c;可高效地为RAG应用程序拆分文本。以下是可用分块器的简要概述&#xff1a; TokenChunker&#xff1a;将文本分割成固定大…

如何通过AB测试找到最适合的Yandex广告内容

想要在Yandex上找到最能吸引目标受众的广告内容&#xff0c;A/B测试是一个不可或缺的步骤。通过对比不同版本的广告&#xff0c;我们可以发现哪些元素最能引起用户的共鸣。首先&#xff0c;设计两个或多个广告版本&#xff0c;确保每个版本在标题、文案、图片等关键元素上有所不…

车载空气净化器语音芯片方案

开发背景&#xff1a; 随着人们生活质量的不断提升和环保意识的日益增强&#xff0c;车内空气质量成为了广大车主关注的焦点。长时间封闭的车厢环境&#xff0c;加之城市空气污染、新车内饰材料释放的有害气体等因素&#xff0c;使得车内空气质量往往不尽如人意&#xff0c;严重…