go语言判断管道是否关闭的误区
前言
本文是探讨的是"在Go语言中,我们是否可以使用读取管道时的第二个返回值来判断管道是否关闭?"
样例
在Go语言中,我们是否可以使用读取管道时的第二个返回值来判断管道是否关闭? 可以看下面的代码
package mainimport "fmt"func main() {// 创建一个整型管道ch := make(chan int)// 启动一个协程往管道发送数据go func() {for i := 0; i < 5; i++ {ch <- i}// 关闭管道close(ch)}()// 能否判断管道是否关闭?if _, ok := <-ch; !ok {fmt.Println("管道已关闭")}
}
探讨 管道的数据结构
在探讨这个问题之前,我们先来了解一下管道的数据结构,从go的源码,我们可以知道,管道是被定义为一个名为hchan的结构体:
type hchan struct {qcount uint //当前队列中剩余的元素个数dataqsiz uint // 环形队列管道容积buf unsafe.Pointer // 环形队列指针elemsize uint16 // 元素大小closed uint32 // 标识管道关闭的状态elemtype *_type // 元素类型recvq waitq // 等待的读元素的协程队列sendq waitq // 等待的写元素的协程队列...
}
其中,有一个属性是我们应该关注的,那就是closed,这玩意标识了管道是否关闭,这玩意为1代表关闭了,为0代表是开启的.
详细分析
好的,接下来我们继续本文探讨的问题在Go语言中,我们是否可以使用管道的第二个返回值来判断管道是否关闭?
先给出结论 : 从严格意义上来讲是不可以的,其实表示是否成功读取数据,但是在缓存区为0的时候,ok的状态和管道状态是一致的,所以会被误认为,这个ok是代表管道的状态
可以看下面的例子
package mainimport ("fmt""time"
)func main() {a2 := make(chan int, 2)go demo(a2)value2, ok2 := <-a2fmt.Printf("value2:%v,ok2:%v\n", value2, ok2)time.Sleep(3 * time.Second)value3, ok3 := <-a2fmt.Printf("value3:%v,ok3:%v\n", value3, ok3)}func demo(a chan int) {defer func() {close(a)fmt.Println("管道已经关闭")}()a <- 1a <- 2
}
解释一下运行流程
- 首先创建了一个缓存区为2的管道a2
- 然后用go关键字
将demo函数开辟出一个新的协程运行,此时demo和main是同一级的关系,同时运行,此时main函数会继续向下执行,发现是从管道中读取一个元素,然后就会等待demo函数会向管道中传入值,demo函数的运行过程是这样的,它发现管道a2的缓存是2,所以刚好把元素存入,然后就执行关闭管道,然后demo协程销毁 - main函数继续执行,接收到a2管道的一个元素之后,然后返回value2和ok2,然后进行打印
- 然后休眠3秒钟
- 然后继续读取a2管道的元素,得到value3和ok3,然后打印
ok2和ok3都为true
’ 管道已经关闭 ’ 这是最先打印的,无论运行多少次,都是一样的,而且我还特地将main函数暂停了3秒,所以我可以保证demo函数已经执行完毕,demo协程已经销毁,然后再执行的第二个管道的数据的读取
逐步调试
- 那我们调试一下,可以发现,执行了make函数创建管道之后,管道没有关闭,我前面特意提了管道的数据结构,其中closed是标识管道是否关闭的
- 继续调试,我们可以发现,在读取完管道a2的第一个值赋值给value2和ok2的时候,此时通道已经关闭
- value2的值为1,ok2为true
- 继续调试,通道还是关闭状态,但是ok3的值还是true,看下面的第二张图
所以读取管道元素传来的第二个值,并不是代表管道是否关闭!
那它代表什么?
其实是代表读取数据是否成功,或者说代表缓存区是否还有数据
首先我们要知道, 关闭了的管道, 我们还是可以进行读取的, 这个设定是因为有缓存的存在, 但是如果管道关闭了的话,又没有值,读取的话,会是类型的默认值和false,也就是读取未成功
当然如果是缓存区为0的情况,ok的值和管道的状态是一致的
var c = make(chan int)
close(c)
value, ok := <-c
fmt.Printf("value:%v \nok:%v \n", value, ok)
运行结果:
相关文章:

go语言判断管道是否关闭的误区
前言 本文是探讨的是"在Go语言中,我们是否可以使用读取管道时的第二个返回值来判断管道是否关闭?" 样例 在Go语言中,我们是否可以使用读取管道时的第二个返回值来判断管道是否关闭? 可以看下面的代码 package mainimport "fmt"…...

如何轻松使用 ChatGPT 进行论文大纲和创作
ChatGPT能够编写复杂的代码、博客文章等,它可以帮助我们做很多事情。今天本篇文章分享的主要内容如何利用 ChatGPT 来撰写论文文章。下面会介绍如何轻松使用 ChatGPT 进行论文大纲和创作! 1、使用 ChatGPT 确定主题 文章非常重要的一个部分就是主题。如…...

【深蓝学院】手写VIO第6章--视觉前端--笔记
第5章相关内容,还是CSDN的传统Markdown编辑器好用。 视觉前段在14讲课程中已经讲过,这里再简单复习一下。 1. 前端工作的定性比较,分析 这一节讲了很多关于前端的方法框架的对比讨论,后面看完了相关的论文之后强烈建议再回来听一…...

用例图 UML从入门到放弃系列之三
1.说明 关于用例图,这篇文章我将直接照搬罗伯特.C.马丁老爷子在《敏捷开发》一书种的第17章,并配上自己的理解,因为这一章写的实在是太精彩了,希望能够分享给大家,共勉。以下是老爷子的原文中文翻译以及豆芽的个人解读…...
NLP大模型
大模型 1、大模型的模型结构 一般指一亿参数以上的模型。 目前以Transformer为基础自回归生成大致可以分为三种架构: Encoder-only的模型,如BERT Encoder-Decoder的模型,如T5。 Decoder-Only的模型,如GPT系列。...
Python- 将一个字符串列表连接成一个单独的字符串
Python中一个常用的技巧:将一个字符串列表连接成一个单独的字符串。 ,.join(list) 是使用Python的 str.join() 方法。 详细解析: join() 方法: 是一个字符串方法,意味着在一个字符串上调用它。它需要一个参数,通常是一个列表或任…...

深眸科技自研AI视觉分拣系统,实现物流行业无序分拣场景智慧应用
在机器视觉应用环节中,物体分拣是建立在识别、检测之后的一个环节,通过机器视觉系统对图像进行处理,并结合机械臂的使用实现产品分类。 通过引入视觉分拣技术,不仅可以实现自动化作业,还能提高生产线的生产效率和准确…...
吴恩达《微调大型语言模型》笔记
微调(fine-tuning)就是利用特有数据和技巧将通用模型转换为能执行具体任务的一种方式。例如,将 GPT-3 这种通用模型转换为诸如 ChatGPT 这样的专门用于聊天的模型。或者将 GPT-4 转换为诸如 GitHub Coplot 这样的专门用于写代码的模型。 这里…...
Java中的Servlet
Java中的Servlet 在Java中,Servlet是一种用于处理Web请求的服务器端组件。Servlet生命周期是Servlet在运行时所经历的一系列阶段,每个阶段都调用特定的方法。以下是Servlet生命周期内调用的方法过程: 初始化阶段(Initialization&…...

Flutter配置Android SDK路径
在使用VSCode作为开发Flutter的工具时,当选择调试设备时,通常看不到android的模拟器,只能看到Chrome之类的。 原因就是Flutter找不到Android的SDK路径,所以无法识别模拟器,我们用flutter doctor命令检查环境时…...

jwt的基本介绍
说出我的悲惨故事给大家乐呵乐呵:公司刚来了一个实习生,老板让他写几个接口给我,我页面还没画完呢。他就把接口给我了,我敲开心,第一次见这么高效率的后端。但我很快就笑不出来了。他似乎不知道HTTP通信是无状态的。他…...
常见Vue事件修饰符浅析
一、.stop修饰符 .stop修饰符代表event.stopPropagation(),加上这个修饰符,就等于在方法中加上了这句代码。 <!--阻止单击事件继续传播--> <a click.stop"doThis"></a>上面的代码等同于如下代码。 <!--阻止单击事件继…...

怎样开始用selenium进行自动化测试?
如果您刚开始使用 Selenium 进行自动化测试,以下是建议的步骤。 1、安装 Selenium 首先,您需要安装 Selenium。Selenium 支持多种编程语言,如 Python、Java、C# 等。可以通过 pip 命令在 Python 中安装 Selenium: pip install …...
二维数组多次排序 或 嵌套list多次排序
可以排序int[ ][ ]的顺序,也可以排序List<List<Integer>> 顺序 为便于理解,以力扣原题为例:1333.餐厅过滤器 原题中给了一个双重数组,并要求返回一个List<Integer>。 方法1: 会用流的,…...

Flutter - 波浪动画和lottie动画的使用
demo 地址: https://github.com/iotjin/jh_flutter_demo 代码不定时更新,请前往github查看最新代码 波浪动画三方库wave lottie动画 Lottie 是 Airbnb 开发的一款能够为原生应用添加动画效果的开源工具。具有丰富的动画效果和交互功能。 # 波浪动画 https://pub-web…...

忘记压缩包密码?解决方法一键找回,省时又便捷!
使用在线rar/zip解密工具,找回rar/zip密码并解密压缩包的方法非常简单。具体步骤如下:首先,在百度上搜索“密码帝官网”,这是一个专业的解密服务网站。然后,点击搜索结果中的链接,进入官网首页。在页面上方…...

“UTONMOS”掀起元宇宙游戏热潮,全球发展前景广阔
我们都知道,市面上无论是PC端的网游还是移动端手游,它如果要做到源源不断的内容输出,不仅取决于游戏公司产品质量和业绩,也与公司的决策和市场沟通密不可分。 元宇宙游戏市场受到关注 近年来,元宇宙游戏市场逐渐升温…...
用idea工具scala 和 Java开发 spark案例:WordCount
目录 一 环境准备 二 scala代码编写 三 java 代码编写 一 环境准备 创建一个 maven 工程 添加下列依赖 <dependency><groupId>org.apache.spark</groupId><artifactId>spark-core_2.12</artifactId><version>${spark.version}</vers…...

【git merge/rebase】详解合并代码、解决冲突
目录 1.概述 2.merge 3.rebase 4.merge和rabase的区别 5.解决冲突 1.概述 在实际开发中,一个项目往往是多个人一起协作的,头天下班前大家把代码交到远端仓库,第二天工作的第一件事情都是从服务器上拉最新的代码,保证代码版本…...
nrm,npm源的管理工具
npm手动切换淘宝源 查看当前的仓库 npm config get registry设置成淘宝源 npm config set registry https://registry.npmmirror.com/设置回官方源 npm config set registry https://registry.npmjs.org/手动切换不免不太方便,而且网上很多资料淘宝源还是过期的链接…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...