golang的channel探索

1、channel是什么?

管道或者是通道。字面意思也就是说是传输的通道或者是管道。
在 Go 语言中,channel 的关键字为 chan,数据流向的表现方式为 <-
分为两种模式:
双向– 表现形式为:chan T,即双向通道。
单向– 表现形式有两种。分别是:chan <- T表示只允许发送的通道,T <- chan表示只允许接收的通道。
除此之外,channel分为缓冲通道无缓冲通道

// 无缓冲
ch1 := make(chan int)// 缓冲区为 3
ch2 := make(chan int, 3)

2、无缓冲channel

缓冲区大小默认为0。
在Go语言中,无缓冲的channel是一种在发送和接收操作之间同步进行的通道。无缓冲channel保证了数据的传递几乎是即时的,发送操作会阻塞,直到另一端的goroutine执行接收操作,反之亦然。这种特性使得无缓冲channel成为goroutine之间同步操作和通信的理想选择。#### 如何创建?

ch := make(chan int)
如何使用?
var ch = make(chan string)go func() {ch <- "包子"}()msg := <-chfmt.Println(msg)

在上面的代码中,发送操作在另一个goroutine中执行,它会阻塞,直到主goroutine执行接收操作。

特性是什么?

无缓冲channel的一个关键特性是它们在发送和接收数据时提供了同步保证
当数据从一个goroutine通过无缓冲channel发送到另一个goroutine时,发送者goroutine会阻塞,直到接收者goroutine接收了数据,这确保了在两个goroutine之间的数据交换是同步的。

使用场景
  • 需要确保在数据处理过程中两个goroutine能够同步操作时。
  • 用来通知一个goroutine另一个goroutine的事件已经发生,比如任务完成或是需要停止执行
注意事项

会发生死锁的两种情况:

  • 没有goroutine接收发送过来的数据
  • 没有goroutine发送数据

3、有缓冲channel

和无缓冲相比,多了一个缓冲区域
无缓冲channel用来同步,有缓冲的channel用来异步
在Go语言中,有缓冲的channel允许在阻塞发送和接收操作之前存储一个固定数量的值。这种类型的channel是异步的:只有在缓冲区满时发送操作才会阻塞,只有在缓冲区空时接收操作才会阻塞

如何使用?
  • 当向有缓冲channel发送数据时,如果缓冲区未满,发送操作就会立即完成,并且发送goroutine可以继续执行不会阻塞。如果缓冲区已满,发送操作将会阻塞,直到有空间可用。
  • 从有缓冲channel接收数据时,如果缓冲区中有数据,接收操作会立即提取数据并继续执行。如果缓冲区为空,接收操作将会阻塞,直到有数据可读。
应用场景是什么?
  • 解耦生产者和消费者的处理速度:当生产者和消费者处理数据的速率不一致时,有缓冲的channel可以作为中间存储,减少直接的依赖
  • 流量控制通过限制缓冲区的大小,可以在一定程度上控制程序的内存使用,防止因为生产速度远大于消费速度而导致的内存溢出
  • 批量处理:有时,等待直到有足够的数据积累在缓冲区中之后再批量处理,可以提高处理效率。
注意事项
  • 缓冲区大小要合适。太小会导致频繁阻塞,太大会增加内存使用。甚至在生产者速度远大于消费者速度时导致内存泄漏
  • 即使channel是有缓冲的,也应避免在没有接收方时向channel发送数据,这可能会导致发送goroutine永久阻塞,从而造成goroutine泄漏。

4、如何判断goroutine是否关闭?

在Go语言中,并没有内置的方法去检测是否关闭
有3种模式可以间接地帮助理解goroutine是否已经完成了它的执行任务:

使用sync.WaitGroup
var wg sync.WaitGroupwg.Add(1)go func() {// goroutine完成时调用defer wg.Done()// 执行任务}()// 等待所有goroutine全部结束(每个都调用done)wg.Wait()

当wait返回时,表示相关的goroutine已经全部完成了。

使用channel
// 根据Go规范,空结构体不分配内存也就是说不占用空间
// 只是一个信号,没有其他意义
done := make(chan struct{})// 启动一个goroutine等待信号go func() {<-done // 等待信号,不关心传递的数据fmt.Println("Received signal, exiting.")}()// 发送信号close(done)
使用context

如果你的goroutine是响应取消信号而结束的,那么可以通过检查context的状态来判断goroutine是否已经结束。

ctx, cancel := context.WithCancel(context.Background())go func() {// 等待取消信号<-ctx.Done()// 清理并退出}()// 发出取消信号cancel()

在这种情况下,当cancel被调用时,依赖于这个context的所有goroutine将开始执行退出流程。

5、如何优雅的关闭goroutine?

  • 使用channel发送退出信号
done := make(chan struct{})go func() {for{select {//等待退出信号case <-done:// 收到信号,退出goroutinereturndefault:// 正常执行任务}}}()// 当需要goroutine结束时,关闭channel 并广播给其他goroutineclose(done)
  • 使用context包控制多个goroutine

如果多个goroutine使用了同一个context,context包提供了一个优雅的解决方案。你可以创建一个context,并在需要停止goroutine时取消它。

ctx, cancel := context.WithCancel(context.Background())go func() {for {select {//检测到取消信号case <-ctx.Done():// 退出goroutinereturndefault:// 正常执行任务}}}()//当需要停止goroutine时,调用cancel通知使用该context的所有goroutine停止cancel()
  • 使用sync.WaitGroup等待goroutine完成优雅关闭
var wg sync.WaitGroupctx, cancel := context.WithCancel(context.Background())wg.Add(1)go func() {defer wg.Done()for {select {//检测到取消信号case <-ctx.Done():// 退出goroutinereturndefault:// 正常执行任务}}}()//通知使用该context的所有goroutine停止cancel()// 等待所有goroutine安全退出wg.Wait()

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

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

相关文章

nodejs使用axios获取url的图片信息并转换为base64

推荐一款AI网站&#xff0c; AI写作与AI绘画智能创作平台 - 海鲸AI | 智能AI助手&#xff0c;支持GPT4设计稿转代码 要使用axios库在Node.js中获取URL的图片信息并将其转换为Base64编码&#xff0c;首先需要安装axios。如果你还没有安装&#xff0c;可以使用以下命令来安装它&…

Docker安装mysql、redis、rabbitmq

【docker 安装mysql】 docker pull mysql:latest docker imagesdocker run -p 3306:3306 --name mysql --restartalways --privilegedtrue \ -v /usr/local/mysql/log:/var/log/mysql \ -v /usr/local/mysql/data:/var/lib/mysql \ -v /usr/local/mysql/conf:/etc/mysql \ -v …

取消退出流程控制方法

在自动化设备动作流程中&#xff0c;人为任意想取消当前动作&#xff0c;常见方法是使用全局变量&#xff0c;实时检测变量决定退出。这里介绍一个System.Threading空间下的 CancellationTokenSource类&#xff0c;他可以设置超时&#xff0c;设置信息等封装 基本使用超时和手…

反向传播和前向传播什么意思

在神经网络训练的上下文中&#xff0c;前向传播和反向传播是两个基本且关键的概念。 前向传播&#xff08;Forward Propagation&#xff09; 前向传播是神经网络中数据流向的第一步。在这个过程中&#xff0c;输入数据从输入层开始&#xff0c;逐层经过隐藏层&#xff0c;直至…

【粉丝福利第一期】小 明

Q1 - 能否自我介绍下&#xff1f; 嗨&#xff0c;大家好&#xff0c;我是 小 明 &#xff08;小明java问道之路&#xff09;&#xff0c;互联网大厂后端研发专家&#xff0c;2022博客之星TOP3/博客专家/CSDN后端内容合伙人、InfoQ(极客时间)签约作者、阿里云签约博主、全网5万…

GO单元测试的使用

Go语言中的测试依赖go test命令,go test命令是一个按照一定约定和组织的测试代码的驱动程序。在包目录内&#xff0c;所有以_test.go为后缀名的源代码文件都是go test测试的一部分&#xff0c;不会被go build编译到最终的可执行文件中。每个测试函数必须导入testing包,测试函数…

PBM学习——从基础到精通!!!

本专栏着重讲解PBM学习所得,学习笔记、心得,并附有视频素材资料,视频详细目录如下: PBM相关参数解释1 PBM相关参数解释2 PBM相关案例实践1 PBM相关案例实践2 PBM相关案例实践2 PBM相关案例实践3 PBM多相流中次相界面设置1 PBM多相流中次相界面设置2 欧拉多相流曳力1 欧拉多…

make/makefile

首先什么是make和makefile呢&#xff1f;先简单说&#xff0c;make是一条命令&#xff0c;makefile是一个文件&#xff0c;这个文件中存的是依赖关系和依赖方法&#xff0c;那么为什么会有这两个东西呢&#xff1f; 首先我们知道在VS2019中&#xff0c;我们可以直接创建一个工程…

474 一零和

题目 给你一个二进制字符串数组 strs 和两个整数 m 和 n 。请你找出并返回 strs 的最大子集的长度&#xff0c;该子集中 最多 有 m 个 0 和 n 个 1 。如果 x 的所有元素也是 y 的元素&#xff0c;集合 x 是集合 y 的 子集 。示例 1&#xff1a;输入&#xff1a;strs ["1…

Linux系统中make/Makefile的介绍

文章目录 前言一、make命令二、makefile功能介绍1.makefile文件的编写格式2.hello.c文件内容3.makefile文件4.安装make命令 总结 前言 在linux系统中&#xff0c;我们对项目文件进行处理的时候会不方便&#xff0c;因此我们需要对文件的编译进行自动化处理。 下面就是在Linux系…

1、docker 基础命令

1、docker 运行镜像 docker run image tag 2、创建dockerfile&#xff08;构建容器的相关命令&#xff09; vim DockerFile 3、docker 构建容器镜像 docker build -t <image_name> . 4、docker 分层 5、查看镜像 docker images 6、docker 执行 docker run --name &…

web组态(BY组态)接入流程

技术文档 官网网站&#xff1a;www.hcy-soft.com 体验地址&#xff1a; www.byzt.net:60/sm 一、数据流向图及嵌入原理 数据流向 嵌入原理 二、编辑器调用业务流程图 三、集成前需要了解的 1、后台Websocket端往前台监控画面端传输数据规则 后台websocket向客户端监控画面…

模型优化_XGBOOST学习曲线及改进,泛化误差

代码 from xgboost import XGBRegressor as XGBR from sklearn.ensemble import RandomForestRegressor as RFR from sklearn.linear_model import LinearRegression as LR from sklearn.datasets import load_boston from sklearn.model_selection import train_test_split,c…

Linux: GDB 调试工具

概念&#xff1a; Linux GDB&#xff08;GNU Debugger&#xff09;是一个功能强大的调试工具&#xff0c;用于调试C、C等编程语言的程序。它可以帮助开发人员定位和修复程序中的错误。 GDB 的使用 &#xff1a; 激活和进入工作模式&#xff1a; gdb 需要调试的文件 进入 …

【Java设计模式】三、

文章目录 0、案例&#xff1a;咖啡屋1、简单工厂模式 静态工厂&#xff08;不属于23种之列&#xff09;2、工厂方法模式3、抽象工厂模式4、建造者模式5、原型设计模式 0、案例&#xff1a;咖啡屋 模拟咖啡店点餐。咖啡有多种&#xff0c;抽象类&#xff0c;子类为各种咖啡。咖…

MySQL查询数据不一致

在您提供的两个查询中&#xff0c;您发现了查询结果的数据量不一致&#xff0c;一个查询结果为404条&#xff0c;另一个查询结果为410条。为了优化这两个查询并确保结果的一致性&#xff0c;您可以尝试以下几点&#xff1a; 1. **统一字段命名**&#xff1a;在两个查询中确保使…

前端面试题汇总(一)

1.html语义化 HTML语义化是指在编写HTML代码时&#xff0c;尽可能使用具有明确含义的标签来描述页面内容的结构和意义&#xff0c;以便让浏览器、搜索引擎和开发者更好地理解和解释页面内容。通过使用语义化的HTML标签&#xff0c;可以提高页面的可访问性、可维护性和可读性&a…

2.29作业

T课上实现通信代码总结&#xff1a; 程序代码&#xff1a; TCPSER.c #include<myhead.h> #define SER_IP "192.168.244.140" //服务器IP #define SER_PORT 9999 //服务器端口号 int main(int argc, const char *argv[]) {//1.创建用于监…

为什么猫咪挑食不吃猫粮?适口性好、普口性价的主食冻干推荐

现代养猫人士往往把自家的小猫看作是生活中的小宝贝&#xff0c;十分宠爱。最令人头疼的就是猫咪挑食不吃猫粮&#xff0c;为什么猫咪挑食不吃猫粮&#xff1f;猫咪挑食应该怎么办&#xff1f;今天为大家分享一个既不让咱宝贝猫咪受罪又可以改善猫咪挑食的方法。 一、为什么猫咪…

深入理解nginx的https sni机制

目录 1. 概述2. 初识sni3. nginx的ssl证书配置指令3.1 ssl_certificate3.2 ssl_certificate_key3.3 ssl_password_file4. nginx源码分析4.1 给ssl上下文的初始化4.2 连接初始化4.3 处理sni回调4.2 动态证书的加载5. 总结阅读姊妹篇: 深入理解nginx的https alpn机制 1. 概述 SN…