Go语言并发模型:像Unix Pipe那样使用channelhyj
wming0523 · · 2882 次点击 · · 开始浏览入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传
简介
Go语言的并发原语允许开发者以类似于 Unix Pipe 的方式构建数据流水线 (data pipelines),数据流水线能够高效地利用 I/O和多核 CPU 的优势。
本文要讲的就是一些使用流水线的一些例子,流水线的错误处理也是本文的重点。
阅读建议
数据流水线充分利用了多核特性,代码层面是基于 channel 类型 和 go 关键字。
channel 和 go 贯穿本文的始终。如果你对这两个概念不太了解,建议先阅读之前公众号发布的两篇文章:Go 语言内存模型(上/下)。
如果你对操作系统中"生产者"和"消费者"模型比较了解的话,也将有助于对本文中流水线的理解。
本文中绝大多数讲解都是基于代码进行的。换句话说,如果你看不太懂某些代码片段,建议补全以后,在机器或play.golang.org 上运行一下。对于某些不明白的细节,可以手动添加一些语句以助于理解。
下一篇文章我们会对 "并行MD5" 这个现实生活的例子进行详细地讲解。
什么是 "流水线" (pipeline)?
对于"流水线"这个概念,Go语言中并没有正式的定义,它只是很多种并发方式的一种。这里我给出一个非官方的定义:一条流水线是 是由多个阶段组成的,相邻的两个阶段由 channel 进行连接;
每个阶段是由一组在同一个函数中启动的 goroutine 组成。在每个阶段,这些 goroutine 会执行下面三个操作:
-
通过 inbound channels 从上游接收数据
-
对接收到的数据执行一些操作,通常会生成新的数据
-
将新生成的数据通过 outbound channels 发送给下游
除了第一个和最后一个阶段,每个阶段都可以有任意个 inbound 和 outbound channel。