通道和 goroutine 是 Go 语言基于 CSP( communicating sequential processes ,通信顺序进程)并发机制的核心部分。阅读本文可以学到一些关于channel的提示和技巧,尤其是“缓冲” channel ,在 “生产者-消费者” 情境中广泛使用了缓冲通道作为队列。

缓冲通道 = 队列

缓冲通道是固定容量的先进先出(FIFO)队列。容量在队列创建的时候就已经固定——其大小不能在运行时更改。

queue := make(chan Item, 10) // queue 的容量是 10

queue 中的一个元素最大可高达 64 KiB , 而且 queue 可以存储指针和非指针元素。如果你坚持要用指针,抑或元素本身就是指针类型,那就需要由你自己来保证在 queue 中被使用的元素所指向的对象是有效的。

queue := make(chan *Item, 10)item1 := &Item{Foo: "bar"}queue 

生产者(将元素放入队列的代码)在把元素入队时可以选择是否阻塞。

// queue 满后会发生阻塞queue  不阻塞的将元素入队// false => 元素没有入队, 会因为queue已满而阻塞

消费者通常从队列中取出元素并处理它们。如果队列为空并且消费者无事可做,就会发生阻塞,直到生产者放入一个元素。

// 取出一个元素, 或者一直等待,直到可以取出元素item := 

如果不希望消费者等待,代码如下:

var ok boolselect { case item =  从queue中取出元素item (或者queue已经关闭,见下)// false => 没有取出元素, queue为空而发生阻塞

关闭缓冲通道

缓冲通道最好是由生产者关闭,通道关闭事件会被发送给消费者。如果你需要在生产者或者消费者之外关闭通道,那么你必须使用外部同步来确保生产者不会试图向已关闭的通道写入(这会引发一个 panic )。

close(queue) // 关闭队列close(queue) // "panic: 关闭一个已关闭的通道"

读取或者写入关闭的通道

你能向已关闭的通道写入么?当然不能。

queue

那么能从已关闭的通道读取么?事实上,在往下翻之前,请先猜测下这段代码的输出结果:

package mainimport "fmt"func main() { queue := make(chan int, 10) queue 

这里有运行以上代码的 链接 https://play.golang.org/p/ot87ro27tFk

(译者注:以下是运行结果)

10200

吃惊吧?如果你猜错了,记住你要先看这里!

在已关闭的通道上的读取行为比较特殊:

  • 如果还有元素没有被取出,那么读取操作会照常进行。
  • 如果队列已空并且已被关闭,读取不会阻塞。
  • 在为空并且已经关闭的通道上读取时会返回通道中元素类型的 “零值”。

这些能让你明白为什么上面的程序会打印出这种结果。但是你又怎么区分读取到的数据是否有效呢?毕竟,“零值”也可能是有效值。答案在下面:

item, valid :=  "item" 有效// false => "queue" 已经关闭, "item" 只是一个 “零值”

因此你在写消费者代码的时候可以这样:

for { item, valid := 

其实,“for..range” 循环是一种更加简单的写法:

for item := range queue { // 处理 item}// 到这里,所有被放入到 queue 中的元素都已经处理完毕,// 并且 queue 也已经关闭

最后,我们可以把非阻塞和检查元素有效性结合到一起:

var ok, valid boolselect { case item, valid =  item 有效, 可以使用// !ok => 通道没有关闭,但是通道为空,稍后重试// ok && !valid => 通道已经关闭,退出轮询

咨询和训练

需要帮助获得一个使用 Golang 的项目?我们在创建和运行生产级 Go 平台软件解决方案领域拥有丰富经验。我们可以帮助你架构和设计 Go 平台项目,或者为使用 Go 工作的团队提供建议和监督。我们也会为希望开展Go项目的团队提供培训或者提升 Golang 知识。这里发现更多 或者 马上联系我们 来讨论你的需求!

Mahadevan Ramachandran

Co-founder & CEO, RapidLoop @mdevanr

go 通道 返回_GCTT 出品 | Go 语言的缓冲通道:提示和技巧相关推荐

  1. Go语言 有缓冲通道、协程池

    文章目录 导言 有缓冲通道.线程池 有缓冲通道是什么? 例子 另一个例子 死锁 容量 vs 长度 WaitGroup 实现协程池 1. 创建数据结构 2. 创建相关函数 1. `digits`函数 2 ...

  2. [Go语言入门] 14 Go语言goroutine和通道详解

    文章目录 14 Go语言goroutine和通道详解 14.1 goroutine 14.2 通道(channel) 声明通道变量 创建通道 通道操作 14.3 管道 14.4 单向通道 14.5 通 ...

  3. go语言学习笔记 — 并发编程 — 通道channel(3):各种各样的通道

    3.1 单向通道 在声明通道时,我们可以设置只发送或只接收.这种被约束操作方向的通道称为单向通道. 声明单向通道 只发送:chan<-,只接收:<-chan var 通道实例 chan&l ...

  4. 如何编写有多个返回值的C语言函数

    1引言 笔者从事C语言教学多年,在教学中学生们常常会问到如何编写具有多个返回值的C语言函数.编写有多个返回值的函数是所有C语言教材里均没有提到的知识点,但在实际教学与应用的过程中我们都有可能会遇到这样 ...

  5. c语言能实现函数返回的语句,C语言实现函数返回多值

    C C语言实现函数返回多值 笔者从事C语言教学多年,在教学中学生们常常会问到如何编写具有多个返回值的C语言函数.编写有多个返回值的函数是所有C语言教材里均没有提到的知识点,但在实际教学与应用的过程中我 ...

  6. c语言在函数中返回数组,关于C语言函数返回数组的问题

    关于C语言函数返回一个数组 c语言中函数不能直接返回一个数组,但是可以用其他方式实现类似功能,不过需要注意: 1.该数组不能是返回函数的局部变量数组,因为局部变量数组在退出函数后会被释放. 可以是全局 ...

  7. c语言怎么返回前一个程序,c语言return返回到哪

    c语言return返回到哪 c语言return,返回给了上一级,比如一个递归程序,从第三层返回到第二层:又比如一个普通的子程序,那就返回到主程序中去. 主程序中return返回给了操作系统. 比如下面 ...

  8. Go 学习笔记(25)— 并发(04)[有缓冲/无缓冲通道、WaitGroup 协程同步、select 多路监听通道、close 关闭通道、channel 传参或作为结构体成员]

    1. 无缓冲的通道 无缓冲的通道(unbuffered channel)是指在接收前没有能力保存任何值的通道. 这种类型的通道要求发送 goroutine 和接收 goroutine 同时准备好,才能 ...

  9. 成功解决VS编译环境下C++语言出现的异常提示:烫烫烫烫烫烫烫烫烫烫

    成功解决VS编译环境下C++语言出现的异常提示:烫烫烫烫烫烫烫烫烫烫 目录 解决问题 解决方法 解决问题 解决方法 "烫"常出现在Windows环境下,执行越界访问的程序,会打印出 ...

最新文章

  1. webpack+react多页面开发架构
  2. 以某一用户名和密码 登录请求脚本_linux expect自动交互脚本
  3. 被迫学计算机,电脑强迫人学习
  4. 人生永无止境的意思是什么_什么是莫比乌斯指环?莫比乌斯环的诅咒
  5. python re模块 字符串匹配_re模块实现正则表达式之match()方法
  6. 【送书】2021年哪些好书值得读(小姐姐配音)
  7. 一步步编写操作系统 1 部署工作环境 1
  8. iOS-属性字符串添加下划线、删除线
  9. Vue iview时间组件DatePicker,设置开始时间和结束时间约束
  10. docker php7 mysql分开,Docker nginx+php74+mysql57, 并安装gd和mysql扩展
  11. 「leetcode」本周小结!(回溯算法系列一)
  12. i7 8750h支持linux,开启游戏本六核时代!酷睿i7-8750H处理器性能实测
  13. Python的pyhanlp库使用(自然语言识别、姓名)
  14. 银行业智能运维的探索与实践
  15. 告诉你Windows PE 是什么东东?详细介绍一下winpe
  16. 如何使用Jmeter对HTTP接口进行压力测试?
  17. 对称加密与非对称加密的区别
  18. linux系统打补丁
  19. OSChina 周日乱弹 —— 种族不同,禁止交往
  20. 来酷科技CEO周铭:以元宇宙生态构建Z时代数字原住民线下体验空间

热门文章

  1. Struts1和Struts2对照
  2. Flash Builder 4.7 类模板编辑设置
  3. 解决 EF whereT(func) 查询的一个性能问题
  4. 编码(人类与机器间的语言)中
  5. Java B2B2C多用户商城 springcloud架构-服务容错保护(Hystrix服务降级)
  6. 函数计算新功能-----支持C#函数
  7. 《Two Dozen Short Lessons in Haskell》学习(十三)迭代及重复的常规模式
  8. WEB前端性能优化小结
  9. Linux下配置JavaWeb环境(持续更新其他软件)
  10. 【转】Java字符串与字符集的基本概念