加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Go并发模型学习

发布时间:2020-12-16 18:37:37 所属栏目:大数据 来源:网络整理
导读:Go concurrency model :原文地址: http://www.oschina.net/translate/go-concurrency-patterns-pipelines?print 特性: 原子并发特性 优势: Golang可 有效的使用I/O和多CPU特性。 1 什么是管道 在Golang对于管道没有明确的定义;它只是许多种并发程序中的

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 的信号,来保证释放发送者。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读