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

Goland 通道

channel通道

目录

channel通道

channel介绍

 channel基本使用

有缓存通道和无缓存通道的区别

 通道的初始化,写入数据到通道,从通道读取数据及基本的注意事项

 channel的关闭和遍历

channel的关闭

为什么关闭

如何优雅地关闭通道

 channel的遍历

 channel的细节

关于channel的只读和只写

 select


channel介绍

  1. channel本质是一个数据结构-队列【示意图】
  2. 数据是先进先出
  3. 线程安全,多goroutine访问时,不需要加锁,channel本身是线程安全的
  4. channel是他有类型的,一个string类型的channel只能存放string类型的数据
  5. 示意图:

 channel基本使用

对于一个intChan类型的变量来讲,intChan地址里面存放了一个16位的管道的地址

有缓存通道和无缓存通道的区别

  1. 无缓存通道:发送方向通道发送数据时会阻塞,直到有接收方接收数据。接收方接收数据时也会阻塞,直到有发送方发送数据。这种通道保证了发送和接收的同步性,非常适合在goroutine之间进行数据交换和同步
  2. 有缓存通道:创建时指定了一个固定大小的缓冲区,发送方向通道发送数据时如果缓冲区未满,则不会阻塞;接收方接受数据时如果缓冲区非空,则不会阻塞。这种通道允许发送和接收的处理速度不同步,提高程序的并发性能。

 通道的初始化,写入数据到通道,从通道读取数据及基本的注意事项

 

 channel的关闭和遍历

channel的关闭

使用内置函数close关闭channel,当channel关闭后,就不能再向channel写数据,但是仍然可以从该channel读取数据。通道的关闭问题并没有这么简单,错误的关闭通道将会引起panic。

为什么关闭
  1. 告知接收方通道已经关闭:关闭通道可以让接受方知道不会再有新的数据发送过来,避免接收方无限等待新数据
  2. 避免死锁:如果通道没有关闭,接收方会一直阻塞在接收操作上
  3. 释放资源:对于使用缓存的通道关闭可以释放缓存区占用的内存。
如何优雅地关闭通道

1)遵守通道关闭原则

2)不要让通道的接收者关闭通道

这篇简书整理了一份关于通道关闭的方法及原则

 channel的遍历

注意:不能使用普通的for循环遍历

channel支持for-range的方式进行遍历

  • 在遍历时,如果channel没有关闭,则会出现deadlock的错误
  • 在遍历时,如果channel已经关闭,则会正常遍历数据,遍历完成后退出

 channel的细节

关于channel的只读和只写
func main() {//管道可以声明为只读或者只写//1.在默认情况下,管道是双向的//var chan1 chan int  可读可写//2.声明为只写var chan2 chan<- intchan2 = make(chan int, 3)chan2 <- 20//num := <-chan2  //error//3.声明为只读var chan3 <-chan intnum2 := <-chan3fmt.Println("num2", num2)
}

只读只写不代表它的类型,只代表了它的属性

 select

使用select可以解决从通道取数据的阻塞问题

func main() {//使用select可以解决从管道取数据的阻塞问题//1.定义一个 管道 10个数据 int类型//2.定义一个 管道 5个数据 string类型intChan := make(chan int, 10)for i := 0; i < 10; i++ {intChan <- i}stringChan := make(chan string, 5)for i := 0; i < 5; i++ {stringChan <- "hello" + fmt.Sprintf("%d", i)}//传统方法在遍历管道时,如果不关闭会导致死锁,但是在实际开发中可能不明确关闭管道的时间//解决办法:selectfor {select {//注意如果管道最终没有关闭,也不 会一直阻塞导致死锁//会自动到下一个case匹配case v := <-intChan:fmt.Printf("从intChan读取了数据%d\n", v)case v := <-stringChan:fmt.Printf("从stringChan读取了数据%s\n", v)default:fmt.Println("都取不到了")return}}}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 读人工智能全传12人工智能导致的问题1
  • 后端老鸟的前端初探:心得与领悟20240713
  • 中介者模式(大话设计模式)C/C++版本
  • nginx的四层负载均衡实战
  • 基于全国产复旦微JFM7K325T+ARM人工智能数据处理平台
  • 实现多层感知机
  • c# 容器变换
  • DELTA: DEGRADATION-FREE FULLY TEST-TIME ADAPTATION--论文笔记
  • TS类型声明文件(一)如何在ts npm包项目中生成 d.ts 文件
  • 黑马头条微服务学习day01-环境搭建、SpringCloud微服务(注册发现、网关)
  • 【自动驾驶/机器人面试C++八股精选】专栏介绍
  • Java技术栈总结:kafka篇
  • 大模型高效参数微调技术
  • Bilibili Android一二面凉经(2024)
  • jenkins系列-06.harbor
  • [微信小程序] 使用ES6特性Class后出现编译异常
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • 【个人向】《HTTP图解》阅后小结
  • Docker 笔记(1):介绍、镜像、容器及其基本操作
  • java中具有继承关系的类及其对象初始化顺序
  • Mac转Windows的拯救指南
  • oldjun 检测网站的经验
  • SAP云平台里Global Account和Sub Account的关系
  • ViewService——一种保证客户端与服务端同步的方法
  • vue数据传递--我有特殊的实现技巧
  • WinRAR存在严重的安全漏洞影响5亿用户
  • 测试如何在敏捷团队中工作?
  • 程序员该如何有效的找工作?
  • 服务器之间,相同帐号,实现免密钥登录
  • 机器学习 vs. 深度学习
  • 今年的LC3大会没了?
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 用jQuery怎么做到前后端分离
  • No resource identifier found for attribute,RxJava之zip操作符
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • (cljs/run-at (JSVM. :browser) 搭建刚好可用的开发环境!)
  • (不用互三)AI绘画:科技赋能艺术的崭新时代
  • (机器学习-深度学习快速入门)第三章机器学习-第二节:机器学习模型之线性回归
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (十)DDRC架构组成、效率Efficiency及功能实现
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (详细文档!)javaswing图书管理系统+mysql数据库
  • (一)Neo4j下载安装以及初次使用
  • (一)spring cloud微服务分布式云架构 - Spring Cloud简介
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .NET CORE Aws S3 使用
  • .NET CORE使用Redis分布式锁续命(续期)问题
  • .Net 知识杂记
  • .net/c# memcached 获取所有缓存键(keys)
  • .NET/C# 如何获取当前进程的 CPU 和内存占用?如何获取全局 CPU 和内存占用?
  • /etc/shadow字段详解
  • @Transactional 详解
  • [ web基础篇 ] Burp Suite 爆破 Basic 认证密码