Golang并发模式--channel高级使用
or-done channel
再pipeline的情况中,我们通过done
来通知goroutine结束。但是,如果我们处理的channel来自系统其它分散的部分,则无法通过done
来控制,因为我们不知道数据流终止的时间,此时需要引入or-done
机制。or-done
机制本质上是对外界数据channel的一个封装,以便我们可以实际控制。
给出代码示例:
package main
func main() {orDone := func(done, c <-chan interface{}) <-chan interface{} {valStream := make(chan interface{})go func() {defer close(valStream)for {select {case <-done:returncase v, ok := <-c:if ok == false { // 外界关闭数据流return}select { // 防止写入阻塞case valStream <- v:case <-done:}}}}()return valStream}
}
tee-channel
tee来源于linux的tee
命令,该模式核心作用是把发来的数据流重新发送到代码中两个不同的地方。我们传递一个channel
,然后返回两个单独的channel
,用以获得相同的值。给出代码示例:
package main
import "fmt"
func main() {tee := func(done <-chan interface{}, in <-chan interface{}) (<-chan interface{}, <-chan interface{}) {out1 := make(chan interface{})out2 := make(chan interface{})go func() {defer close(out1)defer close(out2)for val := range in {var out1, out2 = out1, out2 // 私有变量覆盖for i := 0; i < 2; i++ {select {case <-done:returncase out1 <- val:out1 = nil // 置空阻塞机制完成select轮询case out2 <- val:out2 = nil}}}}()return out1, out2}genetor := func(done <-chan interface{}, n int) <-chan interface{} {genCh := make(chan interface{})go func() {defer close(genCh)for i := 0; i < n; i++ {select {case <-done:returncase genCh <- i:}}}()return genCh}done := make(chan interface{})defer close(done)out1, out2 := tee(done, genetor(done, 10))for val1 := range out1 {val2 := <-out2fmt.Printf("%v, %v\n", val1, val2)}
}
桥接channel
扇出扇出模式中,输入不需要有序。而桥接channel正好与这个相反,该模式适用于输入有序的情况,及多个数据流的输入需要有序的获取。我们必须先处理完一个channel中的数据,然后才能继续向下处理,此时可以把这个多个输入的channel,作为集合单独放到channel中。
给出代码示例:
package mainfunc main() {bridge := func(done <-chan interface{}, chanStream <-chan <-chan interface{}) <-chan interface{} {valStream := make(chan interface{})go func() {defer close(valStream)for {var stream <-chan interface{}select {case maybeStream, ok := <-chanStream:if ok == false { // 只要channel是来自外界的,那么使用时就先判断是否关闭return}stream = maybeStreamcase <-done:return}// orDone机制同样的,防止外界关闭造成channel无法释放for val := range orDone(done, stream) {select {case valStream <- val:case <-done:}}}}()return valStream}
}
Golang并发模式--channel高级使用相关推荐
- Golang并发模式--管线
管线 管线的作用类似于linux的管道,我们利用channel把数据一级级的传递,最终获取数据的结果.管线适用于流处理的方式,而非批处理:流处理可以实时的获取数据. 给出最基础的管线示例,串联加法器和 ...
- Golang并发模式基础
for-select循环 最基本的模式: for {select {case condition 1:// ...case condition 2:// ...case condition n:// ...
- Golang并发:再也不愁选channel还是选锁
周末又到了,为大家准备了一份实用干货:如何使用channel和Mutex解决并发问题,利用周末的好时光,配上音乐,思考一下吧?. 来,问自己个问题:面对并发问题,是用channel解决,还是用Mute ...
- 【Golang 快速入门】高级语法:反射 + 并发
Golang 快速入门 Golang 进阶 反射 变量内置 Pair 结构 reflect 结构体标签 并发知识 基础知识 早期调度器的处理 GMP 模型 调度器的设计策略 并发编程 goroutin ...
- Golang并发模型:轻松入门流水线FAN模式
前一篇文章<Golang并发模型:轻松入门流水线模型>,介绍了流水线模型的概念,这篇文章是流水线模型进阶,介绍FAN-IN和FAN-OUT,FAN模式可以让我们的流水线模型更好的利用Gol ...
- Golang并发模型:合理退出并发协程
goroutine作为Golang并发的核心,我们不仅要关注它们的创建和管理,当然还要关注如何合理的退出这些协程,不(合理)退出不然可能会造成阻塞.panic.程序行为异常.数据结果不正确等问题.这篇 ...
- Go语言中常见的并发模式
Go语言最吸引人的地方是它内建的并发支持.Go语言并发体系的理论是C.A.R Hoare在1978年提出的通信顺序进程(Communicating Sequential Process,CSP).CS ...
- 第09章 Go语言并发,Golang并发
并发指在同一时间内可以执行多个任务.并发编程含义比较广泛,包含多线程编程.多进程编程及分布式程序等.本章讲解的并发含义属于多线程编程. Go 语言通过编译器运行时(runtime),从语言上支持了并发 ...
- golang 并发demo 写入 redis
原文链接:golang 并发demo 写入 redis 源代码: package mainimport ("fmt""runtime""strconv ...
最新文章
- Python学习笔记4—Python字典元组
- 五种方法实现python3-随机生成10位包含数字和字母的密码
- HDU 1518 Square
- python 3.8.2 / 内置的数据结构 / list (类似于 STL 中的 vector)
- At least one JPA metamodel must be present!
- Redux 并不慢,只是你使用姿势不对 —— 一份优化指南
- 原生态HTML文件上传与下载
- 【剑指offer】面试题16:数值的整数次方(Java)
- javacc解析json报错
- Doris之数据划分(全面)
- TOGAF9.2 第I部分 第1章简介
- 如何将Flask项目部署在Ubuntu系统的阿里云主机中(详细完整版:下)
- SSD、Retinanet、RefineDet、CornerNet、ExtremeNet、CenterNet、FSAF、FCOS、FoveaBox相对于yolo的区别
- 升级mojave后辅助功能空白无法
- 企业微信java开发demo_微信企业号demo
- MyBatis知识汇总(第四篇)分页:LIMT(SQL方式),RowBounds(Java对象方式)
- 对于光本身,光走一光年的距离需要多久?————狭义相对论-钟慢效应(时间膨胀)
- 星巴克男子的豆瓣网创业故事
- svn分支开发与主干合并(branch merge)
- java 面试题365