如何优雅的关闭Golang Channel?
Channel关闭原则
不要在消费端关闭channel,不要在有多个并行的生产者时对channel执行关闭操作。
也就是说应该只在[唯一的或者最后唯一剩下]的生产者协程中关闭channel,来通知消费者已经没有值可以继续读了。只要坚持这个原则,就可以确保向一个已经关闭的channel发送数据的情况不可能发生。
暴力关闭channel的正确方法
如果想要在消费端关闭channel,或者在多个生产者端关闭channel,可以使用recover机制来上个保险,避免程序因为panic而崩溃。
func SafeClose(ch chan T) (justClosed bool) {
defer func() {
if recover() != nil {
justClosed = false
}
}()
close(ch)
return true
}
使用这种方法明显违背了上面的channel关闭原则,然后性能还可以,毕竟在每个协程只会调用一次SafeClose,性能损失很小。
同样也可以在生产消息的时候使用recover方法。

礼貌关闭channel方法
还有不少人经常使用sync.Once来关闭channel,这样可以确保只会关闭一次

同样我们也可以使用sync.Mutex达到同样的目的。

要知道golang的设计者不提供SafeClose或者SafeSend方法是有原因的,
他们本来就不推荐在消费端或者在并发的多个生产端关闭channel,
比如关闭只读channel在语法上就彻底被禁止使用了。
优雅的关闭channel的方法
多个消费者,单个生产者.

多个生产者,单个消费者。

就上面这个例子,生产者同时也是退出信号channel的接受者,退出信号channel仍然是由它的生产者
多个生产者,多个消费者

如何优雅的关闭Golang Channel?的更多相关文章
- 如何优雅的关闭golang的channel
How to Gracefully Close Channels,这篇博客讲了如何优雅的关闭channel的技巧,好好研读,收获良多. 众所周知,在golang中,关闭或者向已关闭的channel发送 ...
- golang channel详解和协程优雅退出
非缓冲chan,读写对称 非缓冲channel,要求一端读取,一端写入.channel大小为零,所以读写操作一定要匹配. func main() { nochan := make(chan int) ...
- golang channel关闭后,是否可以读取剩余的数据
golang channel关闭后,其中剩余的数据,是可以继续读取的. 请看下面的测试例子. 创建一个带有缓冲的channel,向channel中发送数据,然后关闭channel,最后,从channe ...
- golang channel 使用总结
原文地址 不同于传统的多线程并发模型使用共享内存来实现线程间通信的方式,golang 的哲学是通过 channel 进行协程(goroutine)之间的通信来实现数据共享: Do not commun ...
- golang channel 用法转的
一.Golang并发基础理论 Golang在并发设计方面参考了C.A.R Hoare的CSP,即Communicating Sequential Processes并发模型理论.但就像John Gra ...
- golang channel的使用以及调度原理
golang channel的使用以及调度原理 为了并发的goroutines之间的通讯,golang使用了管道channel. 可以通过一个goroutines向channel发送数据,然后从另一个 ...
- Golang channel 用法简介
channel 是 golang 里相当有趣的一个功能,大部分时候 channel 都是和 goroutine 一起配合使用.本文主要介绍 channel 的一些有趣的用法. 通道(channel), ...
- Golang Channel用法简编
转自:http://tonybai.com/2014/09/29/a-channel-compendium-for-golang/ 在进入正式内容前,我这里先顺便转发一则消息,那就是Golang 1. ...
- golang channel原理
channel介绍 channel一个类型管道,通过它可以在goroutine之间发送和接收消息.它是Golang在语言层面提供的goroutine间的通信方式. 众所周知,Go依赖于称为CSP(Co ...
随机推荐
- Asp.net core 学习笔记 Razor Page
更新 2019-04-27 最近做了更多的 research 发现微软视乎有意发展 razor page. razor page 的定位是 mvvm, 现在还有个叫 blazor 的东西, 类似用 c ...
- tomcat 中项目配置文件统一目录设置
在tomcat 安装目录中 conf 下的 catalina.properties 文件中 有个 shared.loader= 配置为 shared.loader="${catali ...
- python 【pandas】读取excel、csv数据,提高索引速度
问题描述:数据处理,尤其是遇到大量数据且需要for循环处理时,需要消耗大量时间,如代码1所示.通过data['trip_time'][i]的方式会占用大量的时间 代码1 import time t0= ...
- Linux 细节(杂)
1.所有上传至linux服务器的文件都是英文,避免中文出现乱码导致一些非预期错误,难以查找. 2.删除较危险,linux没有回收站,慎用 rm -rf 3.vi/vim学习地址:http://www. ...
- 序列化---Serializable与Externalizable源码
Serializable接口总结: 1. java.io.Serializable接口是一个标识接口,它没有任何字段和方法,用来表示此类可序列化: 2. 父类声明该接口,则其与其所有子类均可序列化,都 ...
- ArcGIS中删除“点”附带的对应“文本信息”
现状: 用ArcMap打开对应的.mxd文件,导入KML数据后,几何类型“点” - 每一个点都附带对应的文本信息“Placemark”,如下图: 问题:ArcGIS中如何 删除“点”附带的对应“文本信 ...
- 解决MySQL数据库连接太多,多数Sleep
1.查看当前所有连接的详细资料: mysqladmin -uroot -proot processlist 客户端使用: show full processlist 2.只查看当前连接数(Thread ...
- 16、for-of循环
forEach不支持break for-in把数组当做对象来遍历,但是只能遍历出索引值 for-of循环可以遍历出数组的每一项值,支持break 1.for-in示范: 2.for-of示范 3.fo ...
- Python GUI之tkinter
https://blog.csdn.net/yingshukun/article/details/53985080 设置背景图:https://blog.csdn.net/rikkatakanashi ...
- css--父元素塌陷
当父元素内都是漂浮元素时,会造成父高度塌陷的问题.(因为等同于父元素内容为空,所以长,宽都等于空) 我们想要的页面结构是: <!DOCTYPE html> <html lang=&q ...