Golang-如何优雅的关闭一个Channel?

如何优雅的关闭Channel

这部分主要参考自:https://qcrao91.gitbook.io/go/channel/ru-he-you-ya-di-guan-bi-channel

直接关闭存在的问题

主要就是上述“向已关闭的Channel收发,会如何?”中所提到的情况:
1、向已关闭的channel中发送数据,会panic
2、重复关闭已经关闭的channel,会panic。
3、从已关闭的channel接收数据,收到的是0。

一个比较粗糙的实现

利用从读channel的,会返回bool的性质。

func IsClosed(ch <-chan T) bool {select {case <-ch:return truedefault:}return false
}func main() {c := make(chan T)fmt.Println(IsClosed(c)) // falseclose(c)fmt.Println(IsClosed(c)) // true
}

但这样比较粗糙:
一来,对channel的状态进行了修改。
二来,检测的瞬间和关闭瞬间有间隔。
三来,多个同时调用的话,也可能重复关闭。

合理的方案

don't close a channel from the receiver side and don't close a channel if the channel has multiple concurrent senders.

即:不要从一个 receiver 侧关闭 channel,也不要在有多个 sender 时,关闭 channel。

因此考虑从发送端进行关闭。

单一sender的情况

即:
一个 sender,一个 receiver

一个 sender, M 个 receiver

对于这种情况,直接sender方,发完之后关了即可。

多个sender的情况

即:
N 个 sender,一个 reciver

N 个 sender, M 个 receiver

针对一个reciver的情况:

增加一个传递关闭信号的 channel,receiver 通过信号 channel 下达关闭数据 channel 指令。senders 监听到关闭信号后,停止接收数据。

func main() {rand.Seed(time.Now().UnixNano())const Max = 100000const NumSenders = 1000dataCh := make(chan int, 100)stopCh := make(chan struct{})// sendersfor i := 0; i < NumSenders; i++ {go func() {for {select {case <- stopCh:returncase dataCh <- rand.Intn(Max):}}}()}// the receivergo func() {for value := range dataCh {if value == Max-1 {fmt.Println("send stop signal to senders.")close(stopCh)return}fmt.Println(value)}}()select {case <- time.After(time.Hour):}
}

注意:这个代码中,其实并没有关闭channel。这个优雅的处理就是指的:不用他了,将他交给Golang的GC机制去处理。

针对多个reciver的情况:

如果依旧采取上述方案,则可能遇到的情况是:下达了多个关闭命令,依旧造成“向已关闭的channel进行关闭”。因此使用一个“中间人”channel,reciver都向他发送stop,收到第一个后 就向sender发stop。reciver默认长度设置为:Num(senders) + Num(receivers),可以避免阻塞问题。

此部分代码见参考链接的原文即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/724521.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全连接神经网络算法原理(激活函数、前向传播、梯度下降法、损失函数、反向传播)

文章目录 前言1、全连接神经网络的整体结构&#xff1a;全连接神经网络模型是由输入层、隐藏层、输出层所组成&#xff0c;全连接神经网络结构如下图所示&#xff1a;全连接神经网络的每一层都是由一个一个的神经元所组成的&#xff0c;因此只要搞清楚神经元的本质就可以搞清楚…

算法竞赛基础:树状数组

算法竞赛基础&#xff1a;树状数组 是什么&#xff1f; 树状数组虽然语义上是树状&#xff0c;但是实际上还是一个数组。 树状数组的功能就是单点和区间的修改和查询。 例如&#xff0c;如果想增加一个点的值&#xff0c;那么你需要让其上方所有能对齐的树状数组c全部增加相同…

java设计模式课后作业(待批改)

此文章仅记录学习&#xff0c;欢迎各位大佬探讨 实验&#xff08;一&#xff09; 面向对象设计 实验目的 ①使用类来封装对象的属性和功能&#xff1b; ②掌握类变量与实例变量&#xff0c;以及类方法与实例方法的区别&#xff1b; 知识回顾 详情见OOP课件 实验内容…

QChart柱状图

//柱状图// 创建柱状图数据QBarSet *set0 new QBarSet("");*set0 << 1601 << 974 << 655 << 362;QBarSeries *series new QBarSeries();series->append(set0);set0->setColor(QColor("#F5834B"));// 创建柱状图QChart *ch…

github双因子认证

最近换了个安卓手机&#xff0c;打算让之前的苹果手机退役了&#xff0c;所以需要重新搞GitHub的Two-factor authentication 步骤如下&#xff1a; 1. 访问安全中心 https://github.com/settings/security 2. 点击Authenticator app右侧按钮 3. 下载腾讯身份验证器&#xff…

MySQL作业题

一、取得每个部门最高薪水的人员名称 第一步&#xff1a;取得每个部门的最高薪水 select e.deptno, max(e.sal) as maxSal from emp e group by e.deptno; ----------------- | deptno | maxSal | ----------------- | 20 | 3000.00 | | 30 | 2850.00 | | 10 | 5…

CSS常见布局方式

一、静态布局&#xff08;Static Layout&#xff09; 既传统web设计 就是不管浏览器尺寸多少&#xff0c;网页布局就按当时写代码的布局来布置; 块级元素&#xff1a;每个块级元素会在上一个元素下面另起一行&#xff0c;他们会被设置好的margin分离。块级元素是垂直组织的。 …

进程和线程的创建过程

进程和线程的创建过程是不同的,具体如下: 进程的创建过程: 进程的创建过程涉及到写时复制(Copy-on-Write,COW)机制。写时复制是一种可以延迟甚至避免拷贝数据的内存映射方式。新进程的创建过程大致如下: 操作系统为新进程分配必要的资源,如进程控制块等。父进程的内存数据区…

python跨文件夹调用

如图所示&#xff0c;我们要在bin文件夹下的run_patchcore.py文件中调用src/patchcore文件夹下的backbone.py, common.py等文件。如第13行 方法1&#xff1a;将patchcore的上一层目录src添加到环境变量中 run_patchcore.py 文件中写入import sys sys.path.append(/home/rui/P…

苹果群控软件开发必不可少的代码!

在开发苹果群控软件时&#xff0c;编写高质量的代码是至关重要的&#xff0c;这些代码不仅需要实现功能&#xff0c;还需要保证软件的稳定性、安全性和可扩展性&#xff0c;本文将分享四段在苹果群控软件开发中必不可少的源代码&#xff0c;并解释每段代码的作用和实现原理。 一…

HM2019创建分析模型

步骤一&#xff1a;查看单元类类型&#xff08;通过card edit&#xff09;&#xff0c;然后展开模型查看模型信息&#xff1b;步骤二&#xff1a;为材料集里添加新的材料 材料:Al 弹性模量E:70000 泊松比NU:0.33 其中&#xff1a;MAT1表示各向同性材料&#xff0c;E表示弹…

【漏洞复现】ShopXO任意文件读取漏洞

Nx01 产品简介 ShopXO是一套开源的企业级开源电子商务系统&#xff0c;包含PC、H5、微信小程序、支付宝小程序、百度小程序等多个终端&#xff0c;遵循Apache2开源协议发布&#xff0c;基于ThinkPHP5.1框架研发。该系统具有求实进取、创新专注、自主研发、国内领先企业级B2C电商…

three.js可以对3D模型做什么操作和交互,这里告诉你。

Three.js 提供了多种交互功能&#xff0c;可以对 3D 模型进行各种操作和交互。以下是一些常见的交互功能&#xff1a; 鼠标交互 通过鼠标事件&#xff0c;可以实现模型的拖拽、旋转、缩放等操作。例如&#xff0c;可以通过鼠标拖拽来改变模型的位置或角度。 触摸交互 对于支…

95、评估使用多线程优化带来的性能提升

本节评估一下&#xff0c;通过对卷积的 co 维度进行多线程切分之后&#xff0c;对于模型的性能提升。 评估下性能 在进行多线程程序运行时&#xff0c;建议电脑中的 CPU 不要有其他繁重的任务执行。 在相同的环境下&#xff0c;分别运行 5th_codegen 和 6th_multi_thread 下的…

ACWing:99.激光炸弹

#include <iostream> #include <algorithm> using namespace std;const int N 5010;int arr[N][N] {0}; int n,r; int main(){Sios::sync_with_stdio(0),cin.tie(0);cin >> n >> r;r min(r,5001);int X r,Y r; // X Y轴的取值范围 for(int…

Claude3 AI系列重磅推出:引领多模态智能时代的前沿技术,超越GPT-4

Claude3正式发布&#xff1a;号称性能超 GPT-4&#xff0c;免费使用、支持中文 划重点: &#x1f680; Claude3系列发布&#xff0c;包括Haiku、Sonnet和Opus版本&#xff0c;Opus在多个领域超越GPT-4。 &#x1f310; 用户可免费使用Claude3Sonnet模型&#xff0c;支持中文&am…

算法刷题day22:双指针

目录 引言概念一、牛的学术圈I二、最长连续不重复序列三、数组元素的目标和四、判断子序列五、日志统计六、统计子矩阵 引言 关于这个双指针算法&#xff0c;主要是用来处理枚举子区间的事&#xff0c;时间复杂度从 O ( N 2 ) O(N^2) O(N2) 降为 O ( N ) O(N) O(N) &#xf…

Redis的散列插槽及故障转移

散列插槽 散列插槽原理类似于一个哈希散列表&#xff0c;通过哈希算法来映射插槽&#xff0c;并为redis节点分配插槽区间&#xff0c;插槽的所有范围是0~16383 数据key不是与节点绑定&#xff0c;而是与插槽绑定。redis会根据key的有效部分计算插槽值&#xff0c;分两种情况&a…

NetOps-Python实现网络设备SFTP配置

一、网络设备文件管理 1、基本概念 ①配置文件 网络设备配置文件是命令的集合。 ②作用 用户将当前配置保存到配置文件中&#xff0c;以便设备重启后&#xff0c;这些配置能够继续生效。通过配置文件&#xff0c;用户可以非常方便地查阅配置信息将配置文件下载到本地设备&…

latex使用\rm将部分公式或者部分单词设置为正体

在LaTeX中&#xff0c;\rm 是用于设置文字为 “Roman” 字体的命令。这里的 “Roman” 字体通常指的是默认的文本字体&#xff0c;也就是没有特意设置为斜体或粗体的普通字体。然而&#xff0c;\rm 并不总是表示特定的字体样式&#xff0c;而是依赖于当前文档或环境的设置。 在…