文章目录

  • 扇入和扇出
  • 通知退出机制
  • golang实现生成器
    • 最简单的带缓冲的生成器
    • 扇入技术实现增强型生成器
    • 退出通知机制实现自动退出的生成器
    • 一个融合了并发、缓冲、退出通知等多重特性的生成器

扇入和扇出

编程中经常遇到“扇入和扇出”两个概念,所谓的扇入是指将多路通道聚合到一条通道中处理,Go语言最简单的扇入就是使用select聚合多条通道服务;所谓的扇出是指将一条通道发散到多条通道中处理。在Go语言里面实现就是使用go关键字启动多个goroutine并发处理。

中国有句经典的哲学名句叫“分久必合,合久必分”,软件的设计和开发也遵循同样的哲学思想,扇入就是合,扇出就是分。当生产者的速度很慢时,需要使用扇入技术聚合多个生产者满足消费者,比如很耗时的加密/解密服务;当消费者的速度很慢时,需要使用扇出技术,比如Web服务器并发请求处理。扇入和扇出是Go并发编程中常用的技术。

通知退出机制

读取已经关闭的通道不会引起阻塞,也不会导致panic,而是立即返回该通道存储类型的零值。关闭select监听的某个通道能使select立即感知这种通知,然后进行相应的处理,这就是所谓的退出通知机制(close channel to broadcast)。

其中context标准库就是利用这种机制处理更复杂的通知机制的。

golang实现生成器

在应用系统编程中,生成器一般用于生成全局事务号、订单号、序列号和随机数等等。

Go 对这种场景的支持非常简单,其中运用了扇入、扇出以及通知退出的思想。

最简单的带缓冲的生成器

package mainimport ("fmt""math/rand"
)func GenerateIntA() chan int {ch := make(chan int, 10)// 启动一个goroutine用于生成随机数,函数返回一个通道用于获取随机数go func() {for {ch <- rand.Int()}}()return ch
}func main() {ch := GenerateIntA()fmt.Println(<-ch)fmt.Println(<-ch)
}//5577006791947779410
//8674665223082153551

扇入技术实现增强型生成器

package mainimport ("fmt""math/rand"
)func GenerateIntA() chan int {ch := make(chan int, 10)go func() {for {ch <- rand.Int()}}()return ch
}func GenerateIntB() chan int {ch := make(chan int, 10)go func() {for {ch <- rand.Int()}}()return ch
}func GenerateInt() chan int {ch := make(chan int, 20)go func() {// 使用select的扇入技术(Fan in)增加生成的随机源for {select {case ch <- <-GenerateIntA():case ch <- <-GenerateIntB():}}}()return ch
}func main() {ch := GenerateInt()for i := 0; i < 100; i++ {fmt.Println(<-ch)}
}

退出通知机制实现自动退出的生成器

package mainimport ("fmt""math/rand"
)func GenerateIntA(done chan struct{}) chan int {ch := make(chan int)go func() {Lable:for {// 通过select监听一个信号chan来确定是否停止生成select {case ch <- rand.Int():case <- done:break Lable}}close(ch)}()return ch
}func main() {done := make(chan struct{})ch := GenerateIntA(done)fmt.Println(<-ch)fmt.Println(<-ch)// 不再需要生成器,通过close chan发送一个通知给生成器close(done)for v := range ch {fmt.Println(v)}
}

一个融合了并发、缓冲、退出通知等多重特性的生成器

package mainimport ("fmt""math/rand"
)// GenerateIntA done接收通知退出信号
func GenerateIntA(done chan struct{}) chan int {ch := make(chan int, 5)go func() {Lable:for {select {case ch <- rand.Int():case <- done:break Lable}}close(ch)}()return ch
}// GenerateIntB done接收通知信号
func GenerateIntB(done chan struct{}) chan int {ch := make(chan int, 10)go func() {Lable:for {select {case ch <- rand.Int():case <- done:break Lable}}close(ch)}()return ch
}// GenerateInt 通过select 执行扇入操作
func GenerateInt(done chan struct{}) chan int {ch := make(chan int)send := make(chan struct{})go func() {Lable:for {select {case ch <- <-GenerateIntA(send):case ch <- <-GenerateIntB(send):case <- done:send <- struct{}{}send <- struct{}{}break Lable}}close(ch)}()return ch
}func main() {// 创建一个作为退出信号的chandone := make(chan struct{})// 启动生成器ch := GenerateInt(done)// 获取生成器资源for i := 0; i < 10; i++ {fmt.Println(<-ch)}// 通知生产者停止生产done <- struct{}{}fmt.Println("stop produce")
}

参考资料:

《Go核心编程》

golang 扇入扇出以及通知退出机制相关推荐

  1. 关于 FPGA 内部信号扇入扇出

    转自https://www.cnblogs.com/dxs959229640/p/3870189.html 关于 FPGA 内部信号扇入扇出 扇入.扇出系数 扇入系数是指门电路允许的输入端数目.一般门 ...

  2. c语言中的扇入与扇出题目,功能单元的最大扇入扇出工具分析.doc

    功能单元的最大扇入扇出工具分析 文档名称:功能单元最大扇入扇出工具分析 作 者: 日 期: 1. 概念 由于度量的目标是C源代码,所以"功能单元的最大扇入扇出"的含义如下: 功能单 ...

  3. 软件工程考试选择题:模块的扇入扇出 深度宽度

    ABCD A常作为总体设计工具的是HIPO图 B 顶层扇出大,中间扇出小,扇出指一个模块调用的模块数. C组合是一种特殊形式的聚合关系 D状态图 扇入扇出 启发规则 一.改进软件结构提高模块独立性   ...

  4. FPGA Fanout-Fanin(扇入扇出)

    在谈到多扇出问题之前,先了解几个相关的信息,也可以当成是名词解释. 扇入.扇出系数 扇入系数是指门电路允许的输入端数目.一般门电路的扇入系数为1-5,最多不超过8.扇出系数是指一个门的输出端所驱动同类 ...

  5. FPGA入门(三)扇入扇出,逻辑延迟和线延迟,设计主频

    目录 扇入扇出 逻辑延迟,线延迟,逻辑层级 FPGA的内部结构 FPGA最大可以跑到的频率 扇入扇出 http://xilinx.eetrend.com/d6-xilinx/article/2017- ...

  6. c语言中的扇入与扇出题目,功能单元最大扇入扇出工具分析.doc

    : printf() 7.输出结果 2.4 核心代码抽取 通过此工具的源代码,可以获取匹配函数定义语句的功能,函数调用关系的功能,从来实现fan-in,fan-out度量. 3 C and C++ C ...

  7. 【无标题】如何解决多芯光纤的扇入扇出

    多芯光纤是一根光纤有多个纤芯,是和"单芯光纤"相对应的一个概念. 常用的单芯光纤,有多模和单模. 而多芯光纤可以有xnn个纤芯,但它是一根光纤,传输的信号则可以为独立为xn个通道, ...

  8. 【转】关于 FPGA 内部信号扇入扇出

    扇入.扇出系数 扇入系数是指门电路允许的输入端数目.一般门电路的扇入系数为1-5,最多不超过8.扇出系数是指一个门的输出端所驱动同类型门的个数,或称负载能力.一般门电路的扇出系数为8,驱动器的扇出系数 ...

  9. 基础概念——扇入扇出

    一个模块调用其他模块的个数,称为该模块的扇出.扇出越大,设计该模块时需要考虑的问题就越多,因而复杂性越高. 一个模块被其他模块调用的个数,称为该模块的扇入.扇入大些,一般不会影响问题的复杂性,而且扇入 ...

最新文章

  1. 算法(Algorithms)第4版 练习 1.3.11
  2. mysql in边界_mysql中 where in 用法详解
  3. 网络安全系列之二十一 配置IPSEC安全策略
  4. curl 慢 不稳定_慢病毒包装步骤及注意事项
  5. Hadoop HA 深度解析
  6. Markdown 语法及常用资料收集--CheatSheet
  7. 配置zabbix监控windows,cmd运行报错cannot connect to Service Manager: [0x00000005]
  8. dubbo全局异常处理_基于spring aop的dubbo异常统一处理
  9. c#调用c++ dll const char* String类型转换问题。传值,与接收返回值问题
  10. Google整体架构猜想
  11. UVa 10970 大块巧克力
  12. IOS开发之——屏幕适配-AutoLayout代码实现(03)
  13. 智能控制在计算机领域的应用,智能控制的主要应用领域
  14. AndroidUI:Android的Holo Theme
  15. 核心对象激发状态的意义
  16. 七彩背景(Background)
  17. 如何拿下头条号原创标?这里有份6000字的指南
  18. 数据列表组件 jqGrid 二次封装
  19. JS实现拼接图片src
  20. 10种招聘数据的采集方法

热门文章

  1. COLD MOUNTAIN
  2. win7环境下安装Python时可能要到安装不成功的情况,解决问题步骤
  3. qq音乐windows版本也用了部分chromium库啊
  4. Crazyswarm/Crazyflie多无人机集群编队实验平台
  5. Triconex 英维思 7400209-010 I/O 模块
  6. 微信小程序日历(酒店入住日期选择)
  7. 转载:威联通TS-251+,使用emby+kodi 建立本地影音文件服务,及文件分类整理的经验
  8. c++三种实例化对象方式
  9. 2008服务器 自动删除文件,windows-server-2008 – 尝试删除存储在Windows服务器上的目录,在Mac上,包含在Mac上创建的文件,获取“目录不为空”...
  10. python教程79--A4纸增值税电子发票合并打印