Golang并发模型-Pipeline模型、Fan-in Fan-out模型

这段时间由于项目的需要,本人正在研究关于如何优雅的进行go的并发,以下是结合资料和视频的结果,文末会给出参考资料

Go语言的并发模型主要通过goroutine和channel实现,通过这个我们可以更有效地使用IO和CPU

这里我们围绕生成一个随机数并且返回他的平方数的场景来讲解

Generator模式

这里我们设置两个函数,一个是生成随机数,一个是生成平方数

func gen(nums ...int) <-chan int {
    out := make(chan int)
    go func() {
        for _, n := range nums {
            out <- n
        }
        close(out)
    }()
    return out
}

func sq(in <-chan int) <-chan int {
    out := make(chan int)
    go func() {
        for n := range in {
            out <- n * n
        }
        close(out)
    }()
    return out
}

这就是generator模型,将每个并发阶段分开执行,最后汇总到一起

Pipeline模式

顾名思义,就是像一个管道一样联通在一起,从上面流通到下面,此处有一张图,可以更好的说明关系

be75792f60b14c4fbf706bb9564db185.png

 

我们通过channel来传递数据,把功能细分化,从生成一个数到处理一个数最后再到输出,这便是Pipeline模型。在特殊情况下,比如说channel是无缓冲的,那这又是一个同步的函数,只有前一个函数处理了才能到后面一个函数,特别像一个流水线,但是有很多工人,大家都在争相处理着数据

然后我们在main函数里面把他联通起来:

func main() {
    // 设置pipeline。
    c := gen(2, 3)
    out := sq(c)

    // 消费输出。
    fmt.Println(<-out)  // 输出 4
    fmt.Println(<-out)  // 输出 9
}

甚至我们可以设置一个take函数,专门处理输出

func consumer(in <-chan int) {
    for result := range in {
        fmt.Println(result)
    }
}

Fan in Fan out 模型

Fan-in 是指将多个输入合并(多路复用)到一个单一的流中,或者将来自一个源的输入流式传输到多个管道。简单来说,这个模式可以被视为生产者和消费者架构,其中我们有多个生产者向单一消费者发送输入,或者单一生产者向多个消费者发送输入。

类似于这张图

dae760c709364e72a619ae398f87aa02.png 

Fan-out 是指从同一个channel读取的多个函数。这通常用于在一组工作器之间分配工作,以并行化CPU和I/O。例如,你可能有一个生成器函数,它有一个goroutine迭代一系列数字,并将每个数字发送到一个channel中。然后,生成器函数返回存储这些数字的channel。

在Go语言中,fan-in 和 fan-out 模式是处理并发任务时常用的设计模式。这些模式特别适用于可以分解为多个可以并行执行的小任务的耗时任务

下面是一个简单的fan-out和fan-in的例子:


// Fan-out
func gen(nums ...int) <-chan int {
    out := make(chan int)
    go func() {
        for _, n := range nums {
            out <- n
        }
        close(out)
    }()
    return out
}

// Worker
func sq(in <-chan int) <-chan int {
    out := make(chan int)
    go func() {
        for n := range in {
            out <- n * n
        }
        close(out)
    }()
    return out
}

// Fan-in
func merge(cs ...<-chan int) <-chan int {
    var wg sync.WaitGroup
    out := make(chan int)

    // Start an output goroutine for each input channel in cs.
    // output copies values from c to out until c is closed, then calls wg.Done.
    output := func(c <-chan int) {
        for n := range c {
            out <- n
        }
        wg.Done()
    }
    wg.Add(len(cs))
    for _, c := range cs {
        go output(c)
    }

    // Start a goroutine to close out once all the output goroutines are done.
    // This must start after the wg.Add call.
    go func() {
        wg.Wait()
        close(out)
    }()
    return out
}

func main() {
    // Set up the pipeline.
    in := gen(2, 3)

    // Distribute the sq work across two goroutines that both read from in.
    c1 := sq(in)
    c2 := sq(in)

这个Fan-in的启动量我们可以通过CPU来评估。

参考资料

  1. Go Concurrency Patterns: Pipelines and cancellation:这篇文章来自Go官方博客,详细介绍了pipeline模型和如何处理失败情况。
  2. Concurrency in Go: A Practical Guide with Hands-On Examples:这篇文章提供了一系列实用的例子,帮助您理解Go中的并发。
  3. Go Language and AI: Pioneering Concurrent Programming and Analysis
  4. Concurrent Programming in Go 这篇较为简单

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LRU的原理与实现(java)

介绍 LRU的英文全称为Least Recently Used&#xff0c;即最近最少使用。它是一种内存数据淘汰算法&#xff0c;当添加想要添加数据而内存不足时&#xff0c;它会优先将最近一段时间内使用最少的数据淘汰掉&#xff0c;再将数据添加进来。 原理 LRU的原理在介绍中就已经基本说…

linux基础篇:Linux操作系统vi编辑器讲解与常用操作

Linux操作系统vi编辑器讲解与常用操作 一、vi编辑器介绍 vi编辑器是一款功能强大的文本编辑器&#xff0c;广泛应用于Unix和类Unix系统。它是由Bill Joy在1976年开发的&#xff0c;后来演变成vim&#xff08;vi improved&#xff0c;即“改进版的vi”&#xff09;编辑器。vi编…

敏感信息泄露漏洞

法律声明 参与培训需要遵守国家法律法规&#xff0c;相关知识只做技术研究&#xff0c;请勿用于违法用途&#xff0c;造成任何后果自负与本人无关。 中华人民共和国网络安全法&#xff08;2017年6月1日起施行&#xff09; 第二十二条 任何个人和组织不得从事入侵他人网络、干扰…

【JAVASE】带你了解面向对象三大特性之一(继承)

✅作者简介&#xff1a;大家好&#xff0c;我是橘橙黄又青&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;再无B&#xff5e;U&#xff5e;G-CSDN博客 1.继承 1.1 为什么需要继承 Java 中使用类对现实世界中实体来…

ubuntu-server部署hive-part2-安装hadoop

参照 https://blog.csdn.net/qq_41946216/article/details/134345137 操作系统版本&#xff1a;ubuntu-server-22.04.3 虚拟机&#xff1a;virtualbox7.0 安装hadoop ​​​​​​下载上传 下载地址 https://archive.apache.org/dist/hadoop/common/hadoop-3.3.4/ 以root用…

JDK 17 新特性实战,答案整理,最新面试题

JDK 17中的Pattern类增强了哪些功能&#xff1f; 1、新增asMatchPredicate方法&#xff1a; JDK 17的Pattern类新增了asMatchPredicate方法&#xff0c;可以将正则表达式编译为Predicate&#xff0c;方便用于过滤集合中的字符串。 2、增强了Unicode属性支持&#xff1a; JDK …

LLM推理参数(top_k,top_p, temperature, num_beams)

正常LLM做 next token predicate 时&#xff0c;对输出的 logits 做 softmax&#xff0c;选择概率最大的token。 num_beams &#xff1a;当我们设置 num_beams2 后&#xff0c;就使用了 beam search 的方法&#xff0c;每次不是只直接选择概率最大的 token&#xff0c;而是保留…

0基础确定要?进入it行业?

0基础如何进入IT行业&#xff1f; &#x1f31f;想进入IT行业&#xff1f;以下是一些对于0基础的人来说可行的步骤和建议&#xff01;&#x1f31f; "IT"是信息技术(Information Technology)的缩写&#xff0c;它指的是使用计算机、网络、软件和其他设备或系统来存…

数据安全之认识数据库审计系统

随着企业业务数据量的不断增长和数据存储的集中化&#xff0c;数据库成为企业的核心资产之一。然而&#xff0c;数据库面临着各种安全威胁&#xff0c;如SQL注入、权限滥用、数据泄露等。为了保障数据库的安全性和完整性&#xff0c;企业需要采取有效的审计措施来监控和记录数据…

spring源码解析-默认标签解析

spring 默认标签解析 parseDefaultElement处理流程 processBeanDefinition方法解析 processBeanDefinition时序图 元素解析 parseBeanDefinitionElement parseBeanDefinitionElement方法核心源码解析 创建GenericBeanDefinition实例对象 parseMetaElements parseConstructorAr…

平衡二叉树,红黑树,B树和B+树的区别及其应用场景

平衡二叉树 基础数据结构左右平衡高度差大于1会自旋每个节点记录一个数据 平衡二叉树&#xff08;AVL&#xff09; AVL树全称G.M. Adelson-Velsky和E.M. Landis&#xff0c;这是两个人的人名。 平衡二叉树也叫平衡二叉搜索树&#xff08;Self-balancing binary search tree…

通义灵码-ai编码

https://developer.aliyun.com/topic/lingma/activities/202403?taskCode14508&recordIdb1ef3ba27250a5818b1b6ffe418af658#/?utm_contentm_fission_1 「通义灵码 体验 AI 编码&#xff0c;开 AI 盲盒」

使用向量检索和rerank 在RAG数据集上实验评估hit_rate和mrr

文章目录 背景简介代码实现自定义检索器向量检索实验向量检索和rerank 实验 代码开源 背景 在前面部分 大模型生成RAG评估数据集并计算hit_rate 和 mrr 介绍了使用大模型生成RAG评估数据集与评估&#xff1b; 在 上文 使用到了BM25 关键词检索器。接下来&#xff0c;想利用向…

蓝桥杯 十一届C++A组 字符排序 21分(运行超时)

思路&#xff1a; 1. 此题考查的冒泡排序中的交换次数&#xff0c;其实就是考察当前数与后面的逆序对个数问题。而为了最大利用位数&#xff0c;应当使每一位都不小于后面的字符&#xff0c;否则会造成一次逆序对的浪费&#xff08;贪心&#xff0c;为了使总位数最少&#xff…

springBoot--阿里云短信验证

阿里云短信验证 前言阿里云短信服务免费领取100条短信服务1、开通短信服务2、申请签名3、申请模板4、通过子用户获取账号的AccessKey ID 和AccessKey Secret5、使用教程 前言 在我们平时登录中短信验证吗验证在当今是必不可少的&#xff0c;下面是基于阿里云开发的短信验证操作…

达梦数据库安装与实例创建:图形化方式

达梦数据库安装与实例创建&#xff1a;图形化方式 准备工作数据库安装与卸载安装数据库卸载数据库 实例创建与删除创建实例删除实例 准备工作 查看操作系统信息&#xff1a;Linux内核不能低于2.6。 [rootlocalhost ~]# cat /proc/version Linux version 4.19.90-24.4.v2101.k…

PyTorch|Dataset与DataLoader使用、构建自定义数据集

文章目录 一、Dataset与DataLoader二、自定义Dataset类&#xff08;一&#xff09;\_\_init\_\_函数&#xff08;二&#xff09;\_\_len\_\_函数&#xff08;三&#xff09;\_\_getitem\_\函数&#xff08;四&#xff09;全部代码 三、将单个样本组成minibatch&#xff08;Data…

信息论基础:串联信道

串联信道 大学时候看过一期湖南卫视《快乐大本营》&#xff0c;那时候的主持人是何炅和李湘。节目的一个环节是邀请五名观众上台做猜谜游戏。五人带上耳机&#xff0c;坐在一排椅子上&#xff0c;两两中间隔着挡板&#xff0c;好像并排在一起上厕所。李湘把一部电影的名字写在…

Redis集群三种模式

一、Redis集群的三种模式 Redis有三种模式&#xff0c;分别是主从复制、哨兵模式、cluster 主从复制:主从复制是高可用Redis的基础&#xff0c;哨兵和集群都是在主从复制基础上实现高可用的。主从复制主要实现了数据的多机备份&#xff0c;以及对于读操作的负载均衡和简单的故障…

国家开放大学电大《钢结构》形考任务答案

电大搜题 多的用不完的题库&#xff0c;支持文字、图片搜题&#xff0c;包含国家开放大学、广东开放大学、超星等等多个平台题库&#xff0c;考试作业必备神器。 公众号 答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 答案&#xff1a;更多答案&#x…