当前位置: 首页 > news >正文

Go 协程通道使用注意

目录

关闭channel

引入

 不关闭通道是有风险的,主要存在两条:

如何优雅的关闭?

1.只有一个发送者

2.多个发送者

判断通道是否关闭

有缓存和无缓存的通道有什么区别?

错误的关闭通道


关闭channel

close(chan):关闭通道并不会丢失里面的数据,只是让读取通道数据的时候不会读完之后一直阻塞等待新数据写入。

引入

看一看下面的例子:

ch := make(chan int, 1)
ch <- 11
// close(ch) // 如果不关闭,下面会引发死锁// 通道没有关闭的时候会阻塞,程序会永远等待从通道中接收值。而且由于没有其他goroutine来关闭通道,这个阻塞状态将会持续下去,从而引发死锁。
for v := range ch {fmt.Println(v)
}

 不关闭通道是有风险的,主要存在两条:

  1. 出现死锁:如果通道不会再被使用但未关闭,接收者可能会一直等待数据,导致死锁或无意义的等待。
  2. 出现资源泄漏:未关闭的通道可能会导致资源泄漏,因为垃圾收集器不会回收未关闭的通道。而且还要消耗电脑的性能来维护这条管道。

如何优雅的关闭?

在关闭管道的时候,我们要注意:正确地决定何时关闭通道、确保通道不会被多次关闭。(多次关闭同一个通道会报panic)

1.只有一个发送者

如果只有一个发送者,那么这个发送者在完成所有发送操作后可以直接关闭通道:

package mainimport ("fmt""time"
)// 边入边出
func main() {c := make(chan int, 5)go fibonacci(10, c)for v := range c {fmt.Println("out:", time.Now())fmt.Println(v)}
}// 应该由发送数据的一方关闭通道,当数据发送完毕后就是关闭通道的时候。
func fibonacci(n int, c chan int) {x, y := 0, 1for i := 0; i < n; i++ {c <- xfmt.Println("in:", time.Now())time.Sleep(100)x, y = y, x+y}close(c)
}// 大致运行结果:
// in: 2024-07-16 16:00:34.637655 +0800 CST m=+0.000171297
// out: 2024-07-16 16:00:34.637681 +0800 CST m=+0.000197020
// in: 2024-07-16 16:00:34.637952 +0800 CST m=+0.000467725
// 0
// in: 2024-07-16 16:00:34.637963 +0800 CST m=+0.000478508
// out: 2024-07-16 16:00:34.637968 +0800 CST m=+0.000483915
// 1
// in: 2024-07-16 16:00:34.637976 +0800 CST m=+0.000491801
// in: 2024-07-16 16:00:34.637983 +0800 CST m=+0.000499051
// out: 2024-07-16 16:00:34.637978 +0800 CST m=+0.000494157
// 1
// out: 2024-07-16 16:00:34.637999 +0800 CST m=+0.000514485
// 2
// out: 2024-07-16 16:00:34.638006 +0800 CST m=+0.000522241
// 3
// out: 2024-07-16 16:00:34.638013 +0800 CST m=+0.000528591
// 5
// in: 2024-07-16 16:00:34.637988 +0800 CST m=+0.000504017
// in: 2024-07-16 16:00:34.638039 +0800 CST m=+0.000555021
// in: 2024-07-16 16:00:34.638045 +0800 CST m=+0.000561340
// in: 2024-07-16 16:00:34.638049 +0800 CST m=+0.000564725
// in: 2024-07-16 16:00:34.638055 +0800 CST m=+0.000570642
// out: 2024-07-16 16:00:34.638052 +0800 CST m=+0.000568007
// 8
// out: 2024-07-16 16:00:34.638095 +0800 CST m=+0.000610606
// 13
// out: 2024-07-16 16:00:34.638103 +0800 CST m=+0.000619251
// 21
// out: 2024-07-16 16:00:34.63811 +0800 CST m=+0.000626188
// 34

2.多个发送者

当有多个发送者时,可以使用 sync.WaitGroup 来协调这些发送者,并在所有发送者完成后由一个协程关闭通道:

package mainimport ("fmt""sync"
)func main() {ch := make(chan string)var wg sync.WaitGroup// 启动3个协程发送数据for i := 1; i <= 5; i++ {wg.Add(1)go func(num int) {defer wg.Done()for j := 'a'; j <= 'e'; j++ {ch <- fmt.Sprintf("协程%d:%c", num, j)}}(i)}// 启动一个协程来等待所有发送者完成并关闭通道go func() {wg.Wait()close(ch)}()// 接收数据for val := range ch {fmt.Println(val)}fmt.Println("通道已关闭,结束接收")
}

判断通道是否关闭

v, ok := <-ch

如果 ok 为 true,表示成功从 channel 中接收到一个值,并且 channel 还没有关闭。如果 ok 为 false,表示 channel 已经关闭。

当一个 channel 已经关闭而且其中的元素已经全部被取出时,再从管道中取出数据会返回该元素类型的零值,并且 ok 会被设置为 false。这样的检查是为了防止在已关闭的 channel 上进行接收操作时,引发 panic。因为在已关闭的 channel 上进行接收操作会立即返回零值,但如果不进行检查,可能会误认为是从 channel 中接收到了有效的数据。因此,通过检查 ok,我们可以确定是否成功接收到了有效的值。

    c := make(chan int, 5)c <- 1c <- 2c <- 3close(c)v1, ok := <-cfmt.Println(v1, ok) // 1 truev1, ok = <-cfmt.Println(v1, ok) // 2 truev1, ok = <-cfmt.Println(v1, ok) // 3 truev1, ok = <-cfmt.Println(v1, ok) // 0 falsev1, ok = <-cfmt.Println(v1, ok) // 0 false

有缓存和无缓存的通道有什么区别?

参考下面链接:

golang channel有无缓冲区的区别

错误的关闭通道

错误一:多次关闭同一个通道

    c := make(chan int, 5)for i := 0; i < 5; i++ {defer close(c) // 报panic:同一个通道关闭了多次}

错误二:资源泄漏

    for i := 0; i < 5; i++ {c := make(chan int, 5)defer close(c)}

看起来没有错误,运行出来也没有错误。但是可能会导致资源泄漏,因为每次循环迭代中创建的通道不会立即关闭,导致内存和其他资源的泄漏。这五个管道的关闭时间都是在:所在函数运行完毕的时候关闭的。而不是本次循环结束后就立刻关闭。

相关文章:

Go 协程通道使用注意

目录 关闭channel 引入 不关闭通道是有风险的&#xff0c;主要存在两条&#xff1a; 如何优雅的关闭&#xff1f; 1.只有一个发送者 2.多个发送者 判断通道是否关闭 有缓存和无缓存的通道有什么区别&#xff1f; 错误的关闭通道 关闭channel close(chan)&#xff1a;关…...

React基础学习-Day04

React基础学习-Day04 常见的钩子函数及基础使用方式 1.useState useState 是 React 的一个 Hook&#xff0c;用于在函数组件中添加状态。它返回一个状态变量和一个更新该状态的函数。与类组件的 this.state 和 this.setState 相对应&#xff0c;useState 让函数组件也能拥有…...

python爬虫获取网易云音乐评论歌词以及歌曲地址

python爬虫获取网易云音乐评论歌词以及歌曲地址 一.寻找数据接口二.对负载分析三.寻找参数加密过程1.首先找到评论的请求包并找到发起程序2.寻找js加密的代码 四.扣取js的加密源码1.加密函数参数分析①.JSON.stringify(i0x)②bse6Y(["流泪", "强"])③bse6Y…...

中间件的理解

内容来源于学习网站整理。【一看就会】什么是前端开发的中间件&#xff1f;_哔哩哔哩_bilibili 每日八股文~白话说mq&#xff0c;消息中间件_哔哩哔哩_bilibili 例如&#xff1a; 1&#xff09;两个人打电话&#xff0c;中间的通信网络就是中间件。 2&#xff09;菜鸟驿站&…...

django实现用户的注册、登录、注销功能

创建django项目的步骤&#xff1a;Django项目的创建步骤-CSDN博客 一、前置工作 配置数据库&#xff0c;设置数据库引擎为mysql 1、在settings文件中找到DATABASES, 配置以下内容 DATABASES {"default": {ENGINE: django.db.backends.mysql, # 数据库引擎NAME: dja…...

【JAVA 常用API】数据库字段存储JSON格式数据,JAVA中如何将List<Entity>或者对象实体转换为字符串

在Java中&#xff0c;可以使用第三方库如Jackson或Gson来进行JSON的转换。这些库提供了将Java对象转换为JSON字符串的方法。 一&#xff1a;Gson API转Json Getter Setter NoArgsConstructor AllArgsConstructor ToString Builder public class Person {private String name;p…...

AI算不出9.11和9.9哪个大?六家大模型厂商总结了这些原因

大模型“答对”或“答错”其实是个概率问题。关于“9.11和9.9哪个大”&#xff0c;这样一道小学生难度的数学题难倒了一众海内外AI大模型。7月17日&#xff0c;第一财经报道了国内外“12个大模型8个都会答错”这道题的现象&#xff0c;大模型的数学能力引发讨论。 “从技术人员…...

MacBook电脑远程连接Linux系统的服务器方法

一、问题简介 Windows 操作系统的电脑可使用Xshell等功能强大的远程连接软件。通过连接软件&#xff0c;用户可以在一台电脑上访问并控制另一台远程计算机。这对于远程技术支持、远程办公等场景非常有用。但是MacBook电脑的macOS无法使用Xshell。 在Mac上远程连接到Windows服…...

CSS-0_3 CSS和单位

文章目录 CSS的值和单位属性值长度单位CSS和绝对单位CSS和相对单位百分比em & rem视口 颜色单位 碎碎念 CSS的值和单位 我们知道&#xff0c;CSS是由属性和属性值所组成的表 随着CSS的发展&#xff0c;属性不说几千也有几百&#xff0c;我从来不支持去背诵所有的可能性。…...

【代码随想录|贪心算法 455. 分发饼干 376. 摆动序列 53. 最大子数组和】

代码随想录|贪心算法 455. 分发饼干 一、455. 分发饼干1.代码2.问题 二、376. 摆动序列1.代码 三、53. 最大子数组和1.代码 总结 python 一、455. 分发饼干 455. 分发饼干 1.代码 代码如下&#xff08;示例&#xff09;&#xff1a; class Solution:def findContentChildr…...

swift小知识点(二)

1、 Swift 枚举 Swift 中使用 enum 关键词来创建枚举并且把它们的整个定义放在一对大括号内&#xff1a; enum enumname {// 枚举定义放在这里 } 如下事例&#xff1a; // 定义枚举 enum DaysofaWeek {case Sundaycase Mondaycase TUESDAYcase WEDNESDAYcase THURSDAYcase…...

机器人产业发展格局多元化,创业公司突破瓶颈需多维施策

当前&#xff0c;机器人产业的发展格局呈现出多元化、快速增长和技术不断创新的特点。从全球视角来看&#xff0c;机器人市场持续增长&#xff0c;预计到2026年全球人形机器人市场规模将超过20亿美元&#xff0c;到2030年有望突破200亿美元&#xff0c;显示出巨大的市场潜力和发…...

接口测试JMeter-1.接口测试初识

第一章 接口测试初识 1. 接口测试理论基础 “接口测试”一个让人觉得非常高大上的名词&#xff0c;特别是对于刚入门的测试同学而言。随着测试技术不断的深化&#xff0c;“接口测试”出现在我们视野中的频次越来越高。那么接口测试到底是如何做的&#xff1f;接口测试的优势又…...

[米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载-22 TPG图像测试数据发生器设计

软件版本&#xff1a;Anlogic -TD5.9.1-DR1_ES1.1 操作系统&#xff1a;WIN10 64bit 硬件平台&#xff1a;适用安路(Anlogic)FPGA 实验平台&#xff1a;米联客-MLK-L1-CZ06-DR1M90G开发板 板卡获取平台&#xff1a;https://milianke.tmall.com/ 登录“米联客”FPGA社区 ht…...

如何通过企业微信会话存档保护企业利益?

赵总: 张经理&#xff0c;最近行业内频发数据泄露事件&#xff0c;我们的客户资料和内部沟通记录安全吗&#xff1f; 张经理: 赵总&#xff0c;我们已经采取了一系列措施来加强数据安全。特别是针对企业微信的沟通记录&#xff0c;我们最近引入了安企神软件&#xff0c;它能很…...

git修改提交姓名

git config --global user.name “新用户名” git config --global user.email “新邮箱地址” 修改提交的用户名 git config --global user.name “yu***”...

5、在共享内存无指针编程:句柄HANDLE转换为指针

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 共享内存里面不能用指针&#…...

hive动态分区导致xceivercount超限,hdfs无法创建新连接

目录 一、事件复盘&#xff1a; 二、解决方案&#xff1a; 三、讨论 一、事件复盘&#xff1a; hdfs无法创建新的文件&#xff0c;xceivercount超过最大设置&#xff0c;平时每个datanode只有100个左右的连接&#xff0c;突然达到8000以上。 事故原因&#xff0c;跨多天的…...

如何识别Android init 中的缓慢操作

Android 14 开机时间优化措施汇总-CSDN博客 Android 14 开机时间优化措施-CSDN博客根据systrace报告优化系统时需要关注的指标和优化策略-CSDN博客Android系统上常见的性能优化工具-CSDN博客Android上如何使用perfetto分析systrace-CSDN博客Android系统设置kernel log level的…...

JVM:常用工具总结

文章目录 一、jstat工具 一、jstat工具 Jstat工具是JDK自带的一款监控工具&#xff0c;可以提供各种垃圾回收、类加载、编译信息等不同的数据。使用方法为&#xff1a;jstat -gc进程ID每次统计的时间间隔&#xff08;毫秒&#xff09;统计次数。 C代表Capacity容量&#xff0c…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

Python网页自动化Selenium中文文档

1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API&#xff0c;让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API&#xff0c;你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...

Linux安全加固:从攻防视角构建系统免疫

Linux安全加固:从攻防视角构建系统免疫 构建坚不可摧的数字堡垒 引言:攻防对抗的新纪元 在日益复杂的网络威胁环境中,Linux系统安全已从被动防御转向主动免疫。2023年全球网络安全报告显示,高级持续性威胁(APT)攻击同比增长65%,平均入侵停留时间缩短至48小时。本章将从…...

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...

门静脉高压——表现

一、门静脉高压表现 00:01 1. 门静脉构成 00:13 组成结构&#xff1a;由肠系膜上静脉和脾静脉汇合构成&#xff0c;是肝脏血液供应的主要来源。淤血后果&#xff1a;门静脉淤血会同时导致脾静脉和肠系膜上静脉淤血&#xff0c;引发后续系列症状。 2. 脾大和脾功能亢进 00:46 …...