聊聊go语言channel中的一些小技巧

news2024/11/15 18:42:27

写在文章开头

go语言提供了各种非常方便的语法糖,使得我们实现用最少的语法做尽可能高效的事情,而本文就简单介绍如何实现非阻塞处理多个channel,希望对你有帮助。

Hi,我是 sharkChili ,是个不断在硬核技术上作死的技术人,是 CSDN的博客专家 ,也是开源项目 Java Guide 的维护者之一,熟悉 Java 也会一点 Go ,偶尔也会在 C源码 边缘徘徊。写过很多有意思的技术博客,也还在研究并输出技术的路上,希望我的文章对你有帮助,非常欢迎你关注我的公众号: 写代码的SharkChili

因为近期收到很多读者的私信,所以也专门创建了一个交流群,感兴趣的读者可以通过上方的公众号获取笔者的联系方式完成好友添加,点击备注 “加群” 即可和笔者和笔者的朋友们进行深入交流。

在这里插入图片描述

详解channel非阻塞技巧

假设我们现在有这样一个需求,有个有缓冲区bufferedChannel和无缓冲区noBufferChannel,我们希望用一个协程做到查看无缓冲区channel没数据时,再处理有缓冲区channel

对此,我们先介绍一下select语法,按照其工作原理可知,只要某个case无法满足要求就会走到下一个case,由此我们不妨做个猜测,由此我们是否可以将channel的收发作为case分支做到分支1的channel无法处理时执行分支2逻辑呢?

在这里插入图片描述

对此我们给出这样一段代码,可以看到笔者声明了有缓冲区channel1和无缓冲区chann2,然后向有缓冲区chan1投递数据,进而走到select分支。
重点来了,按照正常逻辑,noBufferChannel 是无缓冲区,投递数据1应该阻塞等待消费才对,但是在select分支语法下,在noBufferChannel 数据投递失败之后,走到了下一个分支,该分支的channel收到上文投递的数据1,直接步入逻辑完成打印:

func main() {

	//创建两个channel
	noBufferChannel := make(chan int)
	bufferedChannel := make(chan int, 1)
	//往有缓冲区channel中投递数据,因为有缓冲区,数据投递到缓冲区后,逻辑继续向下
	bufferedChannel <- 1

	//通过select语法避免无缓冲区chan2数据没有被及时消费而阻塞
	select {
	case noBufferChannel <- 1:
		log.Println("无缓冲区channel逻辑执行了")
	case num := <-bufferedChannel:
		log.Println("有缓冲区channel收到数据了:", num)
	default:
		log.Println("defult logic")

	}
}

对应输出结果如下:

 有缓冲区channel收到数据了: 1

由此我们可知,通过select语句,可以非阻塞的执行每一个case逻辑,以本文代码为例,无缓冲区channelcase逻辑发现数据无法投递时,则走到下一个分支查看是否可以执行,结果有缓冲区channel有数据,最终非阻塞走到分支2完成逻辑执行:

在这里插入图片描述

实际上,go语言做到更强大的优化,假如上文两个channel的逻辑都无法执行且没有default分支,它会将这个协程分别注册到所有channel的阻塞队列中,只要某个channel具备处理条件,就会唤醒对应分支。

对应的我们给出这样一个select实现非阻塞轮询的例子,子协程非阻塞轮询所有channel,发现channel都不具备处理的条件,于是将该协程存到各个channel的阻塞队列中。随后主协程消费无缓冲区队列的数据,唤醒无缓冲区的case逻辑:

在这里插入图片描述

对应我们给出示例代码:

func main() {
	var wg sync.WaitGroup
	wg.Add(1)

	//创建两个channel
	noBufferChannel := make(chan int)
	bufferedChannel := make(chan int, 1)

	go func() {
		log.Println("子协程执行,发现无法执行后阻塞")
		defer wg.Done()
		//通过select语法避免无缓冲区chan2数据没有被及时消费而阻塞
		select {
		case noBufferChannel <- 1:
			log.Println("无缓冲区channel逻辑执行了")
		case num := <-bufferedChannel:
			log.Println("有缓冲区channel收到数据了:", num)

		}
	}()
	//休眠1s等待协程1执行完成
	time.Sleep(1 * time.Second)
	log.Println("主协程消费数据")
	num := <-noBufferChannel

	wg.Wait()
	log.Println("执行结束,num:", num)

}

小结

以上便是笔者对于go语言channel非阻塞的工作机制和使用分析,希望对你有帮助。

我是 sharkchiliCSDN Java 领域博客专家mini-redis的作者,我想写一些有意思的东西,希望对你有帮助,如果你想实时收到我写的硬核的文章也欢迎你关注我的公众号: 写代码的SharkChili
因为近期收到很多读者的私信,所以也专门创建了一个交流群,感兴趣的读者可以通过上方的公众号获取笔者的联系方式完成好友添加,点击备注 “加群” 即可和笔者和笔者的朋友们进行深入交流。

在这里插入图片描述

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

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

相关文章

项目进度一

一.双token验证登陆/注册 1.在前端中&#xff0c;得到响应记录acessToken和 refreshToken ,并记录在 localStorage中&#xff0c;当登录之后的请求都要携带着accessToken,如果accessToken过期&#xff0c;就再验证一下refreshToken&#xff0c;如果也过期就需要重新登录&#…

亚马逊测评自养号卖家如何以低成本提高店铺产品曝光率和销量?

在跨境电商领域&#xff0c;随着市场日趋饱和和竞争加剧&#xff0c;卖家普遍面临流量低、转化率低的共同挑战。为了在这种严重的“内卷化”环境中脱颖而出&#xff0c;不少卖家投入了大量的资金和资源&#xff0c;尝试了各种站内和站外的推广方式&#xff0c;但往往因为缺乏成…

Vue2中使用ant-design的tab组件让他一行充满

使用tabs组件默认样式这样 想改成水平居中铺满如下&#xff1a; 需要改下css样式 /deep/ .ant-tabs-nav {width: 100%;& > div {width: 100%;display: flex;align-items: center;}.ant-tabs-tab {flex: 1;text-align: center;}}

Python中matplotlib-legend图例水平排列

在matplotlib中&#xff0c;图例是用来标识不同数据系列或不同类别的标记和颜色的标签。有时候我们希望将图例水平排列&#xff0c;以节省空间并使得图例更加美观。本文将介绍如何在matplotlib中实现图例的水平排列。 方法一&#xff1a;使用legend的loc参数 我们可以通过leg…

Android通知(Notification)的基本用法

Android通知&#xff08;Notification&#xff09;的基本用法 通知&#xff08;Notification&#xff09;是Android系统中比较有特色的一个功能&#xff0c;当某个应用程序希望向用户发出一些提示信息&#xff0c;而该应用程序又不在前台运行时&#xff0c;就可以借助通知来实…

云计算实训43——部署k8s基础环境、配置内核模块、基本组件安装

一、K8S基本概念 1、k8s是什么 K8S是Kubernetes的 缩写&#xff0c;由于k 和 s 之间有⼋个字符&#xff0c;所以因此得名。 Kubernetes 是⼀个可移植的、可扩展的开源平台&#xff0c;⽤于管理容器化 的⼯作负载和服务&#xff0c;可促进声 明式配置和⾃动化。 2、k8s的功…

pico 手臂手部手指完整版

别忘了设置好pico的设置和导入需要的样式 一、动画设置 1.1设置Avatar 遮罩; 1.2创建动画、手指动画的话&#xff0c;我创建了四个&#xff0c;分别对应的是&#xff08;平展、弯曲食指、弯曲其他手指、握拳&#xff09; 1.3建立分层、我建了三层&#xff0c;默认层&#xff…

第二十章 加密 SOAP 主体

文章目录 第二十章 加密 SOAP 主体加密概述加密 SOAP 主体 第二十章 加密 SOAP 主体 本主题介绍如何加密 IRIS Web 服务和 Web 客户端发送的 SOAP 消息正文。 主题“加密安全标头元素”和“使用派生密钥令牌进行加密和签名”描述了如何加密安全标头元素以及加密 SOAP 主体的其…

这10个提示词技巧太强了,用过的人都说真香!

ChatGPT 已经发布一年多了&#xff0c;这一年&#xff0c;我们经常会听到“提示词工程&#xff08;Prompt Engineering&#xff09;”这个术语&#x1f4bb; 在探讨这个概念之前&#xff0c;我们需要先了解什么是Prompt&#xff08;提示词&#xff09;&#x1f914; 简单来说…

面试题复习(0902-0909)

1. 完全背包问题 和01背包唯一的区别是&#xff0c;每件物品都有无限个&#xff08;也就是可以放入背包多次&#xff09; 代码和01唯一的区别在于j的循环是从小到大&#xff0c;不是从大到小。ij谁在外谁在内层区别不大。 #include <bits/stdc.h> using namespace std…

Linux(2)--VmWare虚拟机安装

文章目录 1. VmWare概念2. 安装步骤2.1 下载2.2 安装过程 3. 小结 1. VmWare概念 现在我们要学习Linux了&#xff0c;需要有一台安装Linux系统的计算机。 但是我们又不想放弃Windows&#xff0c;毕竟平时办公、娱乐还得用。 此时可以在电脑上安装VmWare虚拟机软件&#xff0…

C:9-9题目:蛇形矩阵

一、题目介绍&#xff1a; 给你两个整数n&#xff0c;m&#xff0c;请你构造一个n行m列的蛇形方阵&#xff0c;在这个方阵中&#xff0c;数字由1到nm&#xff0c;从最右上角开始&#xff0c;呈环状(逆时针)向内填充。 比如一个3*3的蛇形方阵 3 2 1 4 9 8 5 6 7 二、解题思路&a…

Dropout正则化:提升PyTorch模型性能的神器!

本文展示了在PyTorch模型中添加Dropout正则化如何影响模型在损失和准确率方面的性能。 Dropout正则化在机器学习中的意义是什么&#xff1f; Dropout正则化是机器学习中的一种方法&#xff0c;通过在神经网络中随机丢弃一些单元&#xff08;神经元&#xff09;来模拟同时训练多…

explicit 的作用(如何避免编译器进行隐式类型转换)

目录 1. 隐式转换&#xff08;Implicit Conversion&#xff09; 2. 显式转换&#xff08;Explicit Conversion&#xff09; 3. 隐式转换的风险与显式转换的必要性 4. 隐式类型转换的例子 5. explicit 的作用 6. explicit 在构造函数中的作用 7. explicit 适用于转换操作…

常见网络层(卷积、池化、全连接)与其计算

卷积可视化&#xff1a;卷积神经网络 (CNN) 基本原理和公式_cnn公式-CSDN博客 嵌入大小计算规则【注意评论区全连接层计算规则勘误&#xff1a;Pv Wv Bv】 Conv、MaxPool、FC 池化操作和conv在kernels上计算不一致&#xff0c;在图像尺寸上的规则都是一样的。 公式可以理解…

解决windows远程桌面连接报错:这可能由于GredSSP加密数据库修正

这种问题需要修改一些远程端的安全级别 1.使用快捷键winr打开运行窗口 ------- 输入‘gpedit.msc’ 2.依次展开“计算机配置”->“管理模板”->“系统”->“凭据分配”设置名称&#xff1a; 加密数据库修正 3.双击“加密数据库修正”&#xff0c;将状态改为“启用”&a…

LDRA Testbed(TBrun)软件单元测试_实例讲解(对多次调用的函数打桩)

系列文章目录 LDRA Testbed软件静态分析_操作指南 LDRA Testbed软件静态分析_自动提取静态分析数据生成文档 LDRA Testbed软件静态分析_Jenkins持续集成&#xff08;自动静态分析并用邮件自动发送分析结果&#xff09; LDRA Testbed软件静态分析_软件质量度量 LDRA Testbed软件…

YOLOv10改进:CA注意力机制【注意力系列篇】(附详细的修改步骤,以及代码,目标检测效果优于SE和CBAM注意力)

YOLOv10改进&#xff1a;CA注意力机制【注意力系列篇】&#xff08;附详细的修改步骤&#xff0c;以及代码&#xff09; 如果实验环境尚未搭建成功&#xff0c;可以参考这篇文章 ->【YOLOv10超详细环境搭建以及模型训练&#xff08;GPU版本&#xff09;】 文章链接为&…

电脑pe是什么意思_电脑pe系统作用详细分析

有些小白很好奇&#xff0c;电脑pe是什么意思?所谓的电脑pe系统其实就是当我们的电脑出现问题而不能进入正常系统时候的一种“紧急备用”系统。如果需要重装操作系统的话&#xff0c;以往采用光盘使用的比较多&#xff0c;随着技术的进步&#xff0c;用u盘制作一个pe启动盘去安…

Kubernetes 系列 | k8s入门运维

目录 一、K8S集群搭建1.1 部署方式1.2 了解kubeadm1.3 部署流程1.3.1 初始化配置1.3.2 安装容器运行时1.3.3 安装K8S软件包1.3.4 创建集群 二、集群高可用1.1 集群高可用-堆叠1.2 集群高可用-集群外etcd 三、Pod运维3.1 Pod运维3.2 Pod的生命周期3.3 Pod状况3.4 Pod阶段3.5 容器…