Go channel系列

  • channel入门
  • 为select设置超时时间
  • nil channel用法示例
  • 双层channel用法示例
  • 指定goroutine的执行顺序

双层通道的解释见Go的双层通道

以下是一个双层通道的使用示例。注意下面的示例中使用了"信号通道"(Signal channel),但这里的信号通道是多余的,仅仅只是为了介绍。

信号通道不用来传递数据,而是用来传递消息,用来产生可读、可写的事件,以便让select选中某个分支。产生消息事件的方式有多种,比如直接关闭通道、发送false/true布尔值等等

package mainimport ("fmt""time"
)func main() {// 定义双层通道cccc := make(chan chan int)times := 5for i := 1; i < times+1; i++ {// 定义信号通道ff := make(chan bool)// 每次循环都在双层通道cc中生成内层通道c// 并通过信号通道f来终止f1()go f1(cc, f)// 从双层通道cc中取出内层通道ch// 并向ch通道发送数据ch := <-ccch <- i// 从ch中取出数据for sum := range ch {fmt.Printf("Sum(%d)=%d\n", i, sum)}// 每个循环睡眠一秒钟time.Sleep(time.Second)// 每次循环都关闭信号通道fclose(f)}
}// 双层通道cc用来生成内层通道c
// 并使用信号通道f来终止函数f1()
func f1(cc chan chan int, f chan bool) {c := make(chan int)cc <- cdefer close(c)sum := 0select {// 从内层通道中取出数据,计算和,然后发回内层通道case x := <-c:for i := 0; i <= x; i++ {sum = sum + i}// goroutine将阻塞在此,直到数据被读走c <- sum// 信号通道f可读时,结束f1()的运行// 但因为select没有在for中,该case分支用不上case <-f:return}
}

上面的示例中,函数f1()两个参数,一个是双层通道cc,一个是信号通道f。f1()中首先生成了一个通道c,并发送给了双层通道cc,使得main()中可以从cc中取得这个内层通道c,并向其发送数据。

回到f1()中,select最初会被阻塞,因为内层通道c和信号通道f都没有数据可读。由于main()可以取得内层通道c,并向其发送数据,使得f1()中的select第一个case分支被选中,该分支会计算发送的整数之前的总和,并将计算结果重新发送给内层通道c,让main()可以取得这个计算结果。

上面的示例中有几个细节需要注意:

  1. 在f1()中必须关闭内层通道c,因为main()中的range迭代一个未关闭的通道会一直阻塞,而且每次调用f1()都会重新创建c通道。
  2. 上面的信号通道其实没有起到任何作用。
  3. f1()中的select必须不能放进for循环。因为f1()将数据发回c之后,如果在for中,发f()所在的goroutine将阻塞在select上,由于c通道还没有关闭,这会导致main goroutine因range迭代操作而阻塞,也就是说所有goroutine都被阻塞了,出现了死锁。

所以,当在select中有发送操作的时候,很可能会出现死锁现象。这时,要么为select加上default,要么为select加上超时时间,要么select不要放在for循环中

Go基础系列:双层channel用法示例相关推荐

  1. python循环语句画图_Python基础之循环语句用法示例【for、while循环】

    本文实例讲述了Python基础之循环语句用法.分享给大家供大家参考,具体如下: while 循环 Python中while语句的一般形式: while 判断条件: statements 同样需要注意冒 ...

  2. Go基础系列:指定goroutine的执行顺序

    Go channel系列: channel入门 为select设置超时时间 nil channel用法示例 双层channel用法示例 指定goroutine的执行顺序 当关闭一个channel时,会 ...

  3. string substring的用法_夯实Java基础系列3:一文搞懂String常见面试题,从基础到实战...

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...

  4. Fintech系列(三) -- python对excel操作模块汇总||推荐指数||用法示例

    python对excel操作模块汇总||推荐指数||用法示例 Working with Excel Files in Python 总览 读写Excel的python第三方开源模块 Excel写操作插 ...

  5. 夯实Java基础系列15:Java注解简介和最佳实践

    Java注解简介 注解如同标签 Java 注解概述 什么是注解? 注解的用处 注解的原理 元注解 JDK里的注解 注解处理器实战 不同类型的注解 类注解 方法注解 参数注解 变量注解 Java注解相关 ...

  6. 夯实Java基础系列20:从IDE的实现原理聊起,谈谈那些年我们用过的Java命令

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...

  7. Java工具类系列--Arrays的用法

    原文网址:Java工具类系列--Arrays的用法_IT利刃出鞘的博客-CSDN博客 简介 本文用示例介绍Java中的Arrays的常用方法. Java中的Arrays是用来操作数组的工具类,支持如下 ...

  8. python for item in items_Python中items()系列函数的用法详解

    这篇文章主要介绍了Python中dictionary items()系列函数的用法,很实用的函数,需要的朋友可以参考下 本文实例讲述了Python中dictionary items()系列函数的用法, ...

  9. 【C++自我精讲】基础系列二 const

    [C++自我精讲]基础系列二 const 0 前言 分三部分:const用法.const和#define比较.const作用. 1 const用法 const常量:const可以用来定义常量,不可改变 ...

最新文章

  1. 用python画关系网络图-python networkx 包绘制复杂网络关系图
  2. PHP mysql_real_escape_string() 函数
  3. 【数据库系统概论】考研第六部分重点分析【6.1】
  4. PowerShell使用
  5. window下部署ELK(6.2.2系列)
  6. php websocket 实战,一次WebSocket项目实战后总结的经验
  7. DotNET企业架构应用实践-系列目录
  8. 【ios】如何成为一名ios开发
  9. 取ifrme里的div的代码
  10. java jsp动作_Java中级—JSP九大内置对象和动作
  11. JAVA day06 酒店管理系统
  12. 客户端主机自查DNS故障及应急解决办法
  13. 黑刀 php,黑刀Dezender (PHP解密)
  14. IBM笔记本使用法语输入法,如何键入法语特殊字符?
  15. 目前最好的折叠屏手机也“翻车”了
  16. 基于机器视觉的多机械臂煤矸石分拣机器人系统研究
  17. 基于浏览器的交互式Go学习平台 | Gopher Daily (2020.11.14) ʕ◔ϖ◔ʔ
  18. 山石防火墙怎么映射服务器,hillstone防火墙如何设置
  19. springboot+基于Java的果蔬产品销售系统 毕业设计-附源码131110
  20. 微软Windows Azure云应用开发实践

热门文章

  1. Android Studio一直build、一直refreshing、一直buiding gradle project into的终极解决办法...
  2. css揭秘之linear-gradient
  3. 数据结构---线段树
  4. 用于判断用户注册时,密码强度的JS代码。
  5. 唐山一个葬礼上的豪华车队
  6. 配置多路由的静态路由
  7. 深入浅出Service插件化原理
  8. 深度揭秘Windows 7
  9. 《统一沟通-微软-实战》-7-配置-3-响应组
  10. 根据 JS 自动定义页面缩放比(根据分辨率进行适配)