Go并发模型学习

rually · · 2341 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

Go concurrency model :原文地址:

http://www.oschina.net/translate/go-concurrency-patterns-pipelines?print

特性:原子并发特性

优势:Golang可有效的使用I/O和多CPU特性。

1 什么是管道

在Golang对于管道没有明确的定义;它只是许多种并发程序中的一种。管道是通道连接的一系列阶段, 每个阶段是一组goroutine运行相同的功能。在每个阶段,goroutine运行步骤为:

  • 从上游经过入境通道接受值

  • 对数据执行一些功能操作,通常会产生新的值

  • 从下游经过出通道发送值

除了开始和最后阶段只有一个入境通道或者一个出境通道外,其他每个阶段有任意数量的入境通道和出境通道,。开始阶段有时又称为源或者生产者;最后一个阶段又称为sink或者消费者。


举个例子:

第一阶段:gen,以从列表读出整数的方式转换整数列表到一个通道。gen函数开始goroutine后, 在通道上发送整数并且在在所有的值被发送完后将通道关闭:

func gen(nums ...int) <-chan int {

    out := make(chan int)

    go func() {

        for _, n := range nums {

            out <- n

        }

        close(out)

    }()

    return out

}

第二阶段:sq,从通道接受整数,然后将接受到的每个整数值的平方后返回到一个通道 。在入境通道关闭和发送所有下行值的阶段结束后,关闭出口通道:

func sq(in <-chan int) <-chan int {

    out := make(chan int)

    go func() {

        for n := range in {

            out <- n * n

       }

        close(out)
08
    }()

    return out

}
main函数建立了通道并运行最后一个阶段:它接受来自第二阶段的值并打印出每个值,直到通道关闭:
func main() {

    // Set up the pipeline.

    c := gen(2, 3)

    out := sq(c)
 
    // Consume the output.

    fmt.Println(<-out) // 4

    fmt.Println(<-out) // 9

扇出,扇入

扇出(fan-out):多个函数能从相同的通道中读数据,直到通道关闭;这提供了一种在一组“人员”中分发任务的方式,使得CPU和I/O的并行处理.

扇入(fan-in):一个函数能从多个输入中读取并处理数据,而这多个输入通道映射到一个单通道,该单通道随着所有输入的结束而关闭。

短暂停止

管道函数模型:

  • 当所有的发送操作结束后, 阶段关闭他们的出境通道。

  • 阶段持续接收来自入境通道的值,直到那些通道关闭。


这个模型允许每一个接收阶段通过range循环的写数据,确保一旦所有向下游发送的值发送成功,所有的goroutine退出。 

但在一个真实的管道上,阶段并不总是接收所有的入境值。有时设计是这样的:接收者可能只需要一个子集值就能取得进展。更多时候是一个阶段早早的退出,因为一个入境值代表一个早期阶段的错误。 在这两种情况下接收者不应该等待剩余的值到达,我们想要早期阶段停止产生后续阶段不需要的值。


显式取消

当main没有接受完out所有的值就决定退出时,它必须告知上游状态(upstream stage)的goroutines,让它丢弃正在发送中的数据。通过在一个叫做done的channel上发送数据,即可实现。例子里有两个受阻的发送方,所以发送的值有两组:

下面列出了构建管道的指南:

  • 状态会在所有发送操作做完后,关闭它们的流出 channel

  • 状态会持续接收从流入 channel 输入的数值,直到 channel 关闭或者其发送者被释放。

管道要么保证足够能存下所有发送数据的缓冲区,要么接收来自接收者明确的要放弃 channel 的信号,来保证释放发送者。 



有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:rually

查看原文:Go并发模型学习

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2341 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传