彻底搞懂channel原理(一)

简介: 彻底搞懂channel原理(一)

介绍


channel一些基础介绍这里就不过多涉及了,都1202年了,我不相信用过Go的人没用过channel

当然下图也涵盖了大部分使用姿势。


1668511932082.jpg


有一道使用channel进行任务编排的经典的题。题目如下:

有四个goroutine编号为 1、2、3、4。每秒钟会有一goroutine打印自己的编号。请你实现这个程序,让输出的编号总是按照 1、2、3、4、1、2、3、4、……的顺序打印出来。就像这样,


0.gif


可以自己先思考下,代码也可以通过后台回复击鼓传花获取


原理解析


从一个简单的例子说起

创建一个main.go文件,代码如下


1668511972288.jpg


我们来看看这段代码编译以后长啥样

想得到go程序的汇编代码并不难

可以使用go tool compile -N -l -S main.go生成汇编代码


1668511983165.jpg


或者使用go tool compile -N -l main.go先编译出代码,然后再使用go tool objdump main.o反汇编出代码

还可以通过go build -gcflags -S main.go同样可以得到汇编的代码


上面两种我就不演示了,可以自行实验。他们之中flag的具体含义也可以自行了解。

如果你觉得上面要自己敲代码比较麻烦,我推荐一个更加直接可视化的工具。


1668511997588.jpg


综上,从编译的代码我们可以看出,上述初始化一个channel,ch :=make(chanstruct{})

实际上调用的是runtime.makechan


1668512020214.jpg


从函数中,我们能知道最终返回一个runtime.hchan的指针

runtime.hchan结构


1668512044614.jpg


我们先来解释hchan结构体各个字段的含义,之后在案例介绍中会更加详细的说明他们的作用。


1668512062179.jpg


先来看qcountdataqsiz有什么区别?

你去银行办事,银行有5个办事窗口,那么dataqsiz就等于5。在这里体现的是channel的容量为5。去银行的时候,当前有3个窗口有人正在办事,那么qcount就等于3,体现channel当前有3个数据元素。那么此时银行还可以再接待2个客户,对应还可以往channel发送2个数据元素

其他字段现在看看说明就行了,后面会细讲。


到这里我们就知道创建一个channel本质上就是得到一个runtime.hchan的指针后续对此chan的操作,无非就是对结构体字段进行相对应的操作

同时我们也能猜出,为啥channel能在不同的g中传递消息,而对于使用者来说不用担心并发的问题。

其实就是hchan内部使用互斥锁来保证了并发安全

最后我们来看一下runtime.makechan函数核心实现,当然注释已经很明白了


1668512083102.jpg


可以看到创建的时候有一段switch分支代码,那么什么情况下会走对应的case呢?


1668512095614.jpg


根据上面的信息,我们可以得出

  • 如果创建一个无缓冲channel那么只需要为runtime.hchan本身分配一段内存空间即可。
  • 如果创建的缓冲channel存储的类型不是指针类型会为当前channel和存储类型元素的缓冲区,分配一块连续的内存空间
  • 在默认情况下(缓冲channel存储类型包含指针)会单独为runtime.hchan和缓冲区分配内存。


总结


这篇我们主要介绍了如何获取go程序的汇编代码,通过汇编代码知道创建channel的具体函数runtime.makechan

同时我们还知道不同的创建姿势会导致走向不同的内存空间分配逻辑。

最后通过创建函数我们知道channel在程序运行时是使用runtime.hchan来表示

下一篇我们继续。

相关文章
|
Unix Linux Shell
Linux执行shell脚本提示文件找不到问题解决办法
Linux执行shell脚本提示文件找不到问题解决办法
1586 0
|
11月前
|
存储 人工智能 Serverless
人生剧本模拟器?一键穿越,动画片里也有你!
通过AI技术,只需一张图片和几个关键词,即可生成以自己为主角的剧本并制作成动画片。这项技术简化了创作流程,降低了技术门槛,使每个人都能成为创作者。无论是创意故事、珍贵瞬间还是专属动画,所有人物和故事都由你定义。借助函数计算FC构建Web服务,结合百炼模型服务和ComfyUI工具,实现从剧本撰写到视频合成的一站式自动化流程。点击“阅读原文”参与活动,免费生成你的专属动画,还有礼物和互动奖励等你来拿!
332 11
|
JavaScript
Vue学习之--------插槽【默认插槽、具名插槽、作用域插槽】
这篇文章详细介绍了Vue.js中的插槽概念,包括默认插槽、具名插槽和作用域插槽的使用方式和实际应用示例,通过代码演示了如何在组件中定义和使用插槽来实现内容的灵活替换和展示。
Vue学习之--------插槽【默认插槽、具名插槽、作用域插槽】
|
存储 安全 关系型数据库
InnoDB引擎特性
InnoDB事务型数据库的首选引擎,支持事务安全表(ACID),支持行锁定和外键。MySQL5.5.5之后,InnoDB作为默认存储引擎,InnoDB主要特性有: InnoDB给MySQL提供了具有提交,回滚和崩溃恢复能力的事务安全(ACID兼容)存储引擎。InnoDB锁定在行级并且也在SELECT语句中提供了一个类似Oracle的非锁定读。 InnoDB是为处理巨大数据量的最大性能设计。它的CPU效率可能是任何其他基于磁盘关系的数据库引擎所不能匹敌的。 InnoDB存储引擎完全与MySQL服务器整合,InnoDB存储引擎为在主内存中缓存数据和索引而维持它自己的缓冲池
|
SQL 关系型数据库 MySQL
Flink CDC + Hudi + Hive + Presto构建实时数据湖最佳实践
Flink CDC + Hudi + Hive + Presto构建实时数据湖最佳实践
602 0
|
编译器
使用海思v500交叉编译器编译qt5.4.2版本
使用海思v500交叉编译器编译qt5.4.2版本
378 1
|
机器学习/深度学习 自然语言处理 TensorFlow
深度学习技术
深度学习技术
455 0
|
前端开发 JavaScript 开发者
Layui 简单介绍及入门
Layui 简单介绍及入门
341 0
带你读《5G大规模天线增强技术》——2.4.4 路径损耗计算
带你读《5G大规模天线增强技术》——2.4.4 路径损耗计算
|
存储 Web App开发 编解码
Web3.0 · 基础层技术 · SCQA模型趣谈密码学
Web3.0 · 基础层技术 · SCQA模型趣谈密码学
1081 0
Web3.0 · 基础层技术 · SCQA模型趣谈密码学