【go】channel结构体源码和读写和关闭过程

news/2024/10/17 18:23:32/
  • 简而言之,channel维护了一个带指针的接受和发送的队列,其中包含mutex锁保证并发安全,数据类型,元素个数,元素大小,channel状态
  • 然后读写操作,先看队列是否可以取出,然后看缓冲区,最后放入接受/发送队列
  • 关闭就是唤醒所有goroutine然后将他们的标志位设为1,表示关闭,以后有人访问就是nil

结构体源码

type hchan struct {qcount   uint           // 当前队列中元素的数量dataqsiz uint           // 缓冲区大小,即可以缓存的元素数量buf      unsafe.Pointer // 指向队列的缓冲区elemsize uint16         // 每个元素的大小closed   uint32         // channel 是否已关闭的标志elemtype *_type         // channel 中元素的类型sendx    uint           // 下一次发送元素的位置recvx    uint           // 下一次接收元素的位置recvq    waitq          // 等待接收的 goroutine 队列sendq    waitq          // 等待发送的 goroutine 队列lock     mutex          // 用于保护 channel 的互斥锁
}

发送数据

当一个 goroutine 要向 channel 中发送数据时,它会执行 chansend 函数。

  1. 这个函数首先会对 channel 进行加锁,然后判断是否有等待接收的 goroutine
  2. 如果有,则直接将数据发送给它;否则,如果缓冲区未满,则将数据放入缓冲区,队列中元素数量加一;
  3. 如果队列已满,则将当前 goroutine 加入等待发送的 goroutine 队列中,并阻塞它,等待其他 goroutine 接收数据。

接受数据

当一个 goroutine 要从 channel 中接收数据时,它会执行 src/runtime/chan.go 中的 chanrecv 函数。

  1. 这个函数也会对 channel 进行加锁,然后判断是否有等待发送的 goroutine,如果有,则直接从它那里接收数据;
  2. 否则,如果缓冲区元素的数量大于 0,则从缓冲区中取出一个元素,并将队列中元素数量减一。
  3. 如果缓冲区为空,则将当前 goroutine 加入等待接收的 goroutine 队列中,并阻塞它,等待其他 goroutine 发送数据。

关闭channel

当一个 goroutine 要关闭 channel 时,它会执行 src/runtime/chan.go 中的 closechan 函数。

  1. 这个函数会对 channel 进行加锁,然后将 closed 标志置为 1,表示 channel 已经关闭。
  2. 然后遍历等待发送和等待接收的 goroutine 队列,将它们全部唤醒,并返回一个特殊的值来表示 channel 已经关闭。

http://www.ppmy.cn/news/55592.html

相关文章

基于Springboot的班级综合测评管理系统的设计与实现

摘要 随着互联网技术的高速发展,人们生活的各方面都受到互联网技术的影响。现在人们可以通过互联网技术就能实现不出家门就可以通过网络进行系统管理,交易等,而且过程简单、快捷。同样的,在人们的工作生活中,也就需要…

mybatis generator自定义model的代码注释

mbg相信大家都比较熟悉,可以自动化的生成数据库表对应的model,mapper。但是最近在使用mbg的时候遇到了这样的问题: 1、生成的model虽然可以根据数据库字段的comment生成注释,但这些注释仅对后端开发人员可见,如果想让前…

4 月份 火火火火 的开源项目

盘点 4 月份 GitHub 上 Star 攀升最多的开源项目,整个 4 月份最火项目 90% 都是 AI 项目(准确的说,最近半年的热榜都是 AI 项目) 本期推荐开源项目目录: 1. AI 生成逼真语音 2. 复旦大模型 MOSS! 3. 让画中…

23年4月工作笔记整理(前端)

目录 一、业务需求二、前端学习 一、业务需求 1.单个校验触发this.$refs[‘表单ref’].validateField(‘单个校验名’) 2.return 只会退出当前循环,不是退出方法,与break类似 3.store里的数据刷新会消失,可以采取重新调接口,或者…

Android的AAC架构

AAC Android Architecture Components的简称,是一套用来搭建具有生命周期感知架构的系列组件,在2017年 GoogleI/O大会上发布。 dependencies {def lifecycle_version "2.2.0"implementation "androidx.lifecycle:lifecycle-livedata-ktx…

写在28岁,回看3年前的自己,庆幸当时入了软件测试这行

为什么会学习软件测试? 已经28岁了,算一下快过去3年了,刚毕业那会工作了一年,因为自己当时很迷茫(觉得自己挺废的),所以就没去工作就一直在家,家里固定每个月给点生活费&#xff0c…

移动架构47_视图绑定组件ViewBinding

Android移动架构汇总​​​​​​​ 文章目录 一、控件的声明二、ViewBinding的基本使用三、ViewBinding特点四、ViewBinding的封装五、源码 一、控件的声明 在Activity中绑定布局中的控件一般有三种实现方式: 第一种用最原生态的findViewById方法来绑定第二种方…

辨析 确认范围、核实产品、质量控制、项目收尾

确认范围、核实产品、质量控制、项目收尾 辨析 确认范围与核实产品 确认范围针对项目可交付成果,由客户或发起人在阶段末确认验收的过程 核实产品针对产品是否完成,由客户或发起人在阶段末确认产品是否完整 确认范围与质量控制 不同点 强调内容不同…