go Channel 原理 (一)

Channel

设计原理

不要通过共享内存的方式进行通信,而是应该通过通信的方式共享内存。

在主流编程语言中,多个线程传递数据的方式一般都是共享内存
在这里插入图片描述
Go 可以使用共享内存加互斥锁进行通信,同时也提供了一种不同的并发模型,即通信顺序进程(Communicating sequential processes,CSP)。Goroutine 和 Channel 分别对应 CSP 中的实体和传递信息的媒介,Goroutine 之间会通过 Channel 传递数据。
在这里插入图片描述
上图中的两个 Goroutine,一个会向 Channel 中发送数据,另一个会从 Channel 中接收数据,它们两者能够独立运行并不存在直接关联,但是能通过 Channel 间接完成通信。

数据结构

type hchan struct {

   // 循环队列
   
   // 元素数量 
   qcount   uint           // total data in the queue
   // 队列的长度
   dataqsiz uint           // size of the circular queue
   // 缓冲区大小 有缓冲的 channel 才有
   buf      unsafe.Pointer // points to an array of dataqsiz elements
   // 已发送和接收元素在队列中的索引
   sendx    uint   // send index
   recvx    uint   // receive index
   
   // 元素类型和大小
   elemsize uint16
   elemtype *_type // element type
   
   // channel 是否已关闭
   closed   uint32

   // 等待接受和发送的 goroutine 队列
   recvq    waitq  // list of recv waiters
   sendq    waitq  // list of send waiters

   // lock protects all fields in hchan, as well as several
   // fields in sudogs blocked on this channel.
   //
   // Do not change another G's status while holding this lock
   // (in particular, do not ready a G), as this can deadlock
   // with stack shrinking.
   lock mutex
}

sendqrecvq 存储了当前 Channel 由于缓冲区空间不足而阻塞的 Goroutine 列表,这些等待队列使用双向链表 runtime.waitq 表示,链表中所有的元素都是 runtime.sudog 结构,runtime.sudog 表示一个在等待列表中的 Goroutine。

type waitq struct {
    first *sudog
    last  *sudog
}

在这里插入图片描述

创建 channel

通道有两个方向,发送和接收。
一般而言,使用 make 创建一个能收能发的通道:

// 无缓冲通道
ch1 := make(chan int)
// 有缓冲通道
ch2 := make(chan int, 10)

创建 chan 的函数是 makechan:

func makechan(t *chantype, size int64) *hchan

创建的 chan 是一个指针,所以我们能在函数间直接传递 channel,而不用传递 channel 的指针。

const hchanSize = unsafe.Sizeof(hchan{}) + uintptr(-int(unsafe.Sizeof(hchan{}))&(maxAlign-1))

func makechan(t *chantype, size int64) *hchan {
   elem := t.elem

   // 省略了检查 channel size,align 的代码
   // ……

   var c *hchan
   // 如果元素类型不含指针 或者 size 大小为 0(无缓冲类型)
   // 只进行一次内存分配
   if elem.kind&kindNoPointers != 0 || size == 0 {
      // 如果 hchan 结构体中不含指针,GC 就不会扫描 chan 中的元素
      // 只分配 "hchan 结构体大小 + 元素大小*个数" 的内存
      c = (*hchan)(mallocgc(hchanSize+uintptr(size)*elem.size, nil, true))
      // 如果是缓冲型 channel 且元素大小不等于 0(大小等于 0的元素类型:struct{})
      if size > 0 && elem.size != 0 {
         c.buf = add(unsafe.Pointer(c), hchanSize)
      } else {
         // race detector uses this location for synchronization
         // Also prevents us from pointing beyond the allocation (see issue 9401).
         // 1. 非缓冲型的,buf 没用,直接指向 chan 起始地址处
         // 2. 缓冲型的,能进入到这里,说明元素无指针且元素类型为 struct{},也无影响
         // 因为只会用到接收和发送游标,不会真正拷贝东西到 c.buf 处(这会覆盖 chan的内容)
         c.buf = unsafe.Pointer(c)
      }
   } else {
      // 进行两次内存分配操作
      c = new(hchan)
      c.buf = newarray(elem, int(size))
   }
   // 更新字段
   c.elemsize = uint16(elem.size)
   c.elemtype = elem
   c.dataqsiz = uint(size)

   return c
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Postman设置请求间自动保存返回参数,方便后续请求调用,减少复制粘贴

postman中常常出现:有两个请求,一个请求首先获取验证码或者token,再由得到的验证码或token编写body发送另一个请求。如何设置两个请求间自动关联相关数据呢? 通过环境存储全局变量 现在有两个请求如下图,生成验证码是…

代理IP如何助力旅游信息聚合?

在数字化时代,旅游信息聚合对于提升服务质量、优化用户体验起着至关重要的作用。随着在线旅游预订的普及,旅游信息的采集、整合和呈现成为了一个复杂而关键的过程。在这个过程中,代理IP技术以其独特的优势,为旅游信息聚合提供了强…

服务器硬件以及RAID配置

目录 一、RAID磁盘阵列原理(嘎嘎重要) 1、RAID的概述 2、常用的RAID 2.1、RAID 0 2.2、RAID 1 2.3、RAID 5 2.5、RAID 10 3、阵列卡介绍 二、建立软件RAID磁盘阵列 1、添加硬盘 2、使用fdisk分区,类型为fd 3、mdata命令使用参数 …

CXL:拯救NVMe SSD缓存不足设计难题-2

LMB提出了基于CXL协议的内存扩展框架和内核模块。该方案利用CXL内存扩展器作为物理DRAM源,旨在提供一个统一的内存分配接口,使PCIe和CXL设备都能方便地访问扩展的内存资源。通过这个接口,NVMe驱动和CUDA的统一内存内核驱动可以直接高效地访问…

探索人工智能和LLM对未来就业的影响

近年来,人工智能(AI)迅猛发展,引发了人们的兴奋,同时也引发了人们对就业未来的担忧。大型语言模型(LLM)就是最新的例子。这些强大的人工智能子集经过大量文本数据的训练,以理解和生成…

【贡献法】2262. 字符串的总引力

本文涉及知识点 贡献法 LeetCode2262. 字符串的总引力 字符串的 引力 定义为:字符串中 不同 字符的数量。 例如,“abbca” 的引力为 3 ,因为其中有 3 个不同字符 ‘a’、‘b’ 和 ‘c’ 。 给你一个字符串 s ,返回 其所有子字符…

【Arduino】实验使用ESP32控制可编程继电器制作跑马灯(图文)

今天小飞鱼实验使用ESP控制继电器,为了更好的掌握继电器的使用方法这里实验做了一个跑马灯的效果。 这里用到的可编程继电器,起始原理并不复杂,同样需要ESP32控制针脚输出高电平或低电平给到继电器,继电器使用这个信号控制一个电…

Linux 网络:网卡 promiscuous 模式疑云

文章目录 1. 前言2. 问题场景3. 问题定位和分析4. 参考资料 1. 前言 限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。 2. 问题场景 调试 Marvell 88E6320 时,发现 eth0 出人意料的进入了 promis…

【吊打面试官系列-MyBatis面试题】MyBatis 与 Hibernate 有哪些不同?

大家好,我是锋哥。今天分享关于 【MyBatis 与 Hibernate 有哪些不同?】面试题,希望对大家有帮助; MyBatis 与 Hibernate 有哪些不同? 1、Mybatis 和 hibernate 不同,它不完全是一个 ORM 框架,因…

grpc学习golang版( 四、多服务示例 )

系列文章目录 第一章 grpc基本概念与安装 第二章 grpc入门示例 第三章 proto文件数据类型 第四章 多服务示例 第五章 多proto文件示例 第六章 服务器流式传输 第七章 客户端流式传输 第八章 双向流示例 文章目录 一、前言二、定义proto文件三、编写server服务端四、编写Client客…

盘点全球Top10大云计算平台最热门技能证书

小李哥花了一年半时间终于考下全球10大云的77张认证,今天盘点下各个云的热门证书,希望能帮到非CS专业转IT和刚刚入行云计算的小伙伴。 排名取自23年Yahoo云计算市场份额排名报告,我会从云平台、证书价格、证书热门程度做推荐。 1️⃣亚马逊云…

MathType7.6永久破解激活码注册码 包含安装包下载

MathType是一款强大的数学公式编辑器,它能够帮助用户轻松编辑各种复杂的数学公式和符号。无论是学生、教师还是科研人员,MathType都能提供专业、精确的数学公式编辑服务。 在学习和工作中,我们常常会遇到需要编写数学公式的情况。然而&#x…

Python 算法交易实验74 QTV200第二步(改): 数据清洗并写入Mongo

说明 之前第二步是打算进入Clickhouse的,实测下来有一些bug 可以看到有一些分钟数据重复了。简单分析原因: 1 起异步任务时,还是会有两个任务重复的问题,这个在同步情况下是不会出现的2 数据库没有upsert模式。clickhouse是最近…

除了重塑千行百业,生成式AI还能改善运动健康

飞速发展的生成式AI与大模型技术,不但正在重塑千行百业,而且还能有效改善人们的运动健康。 生成式AI技术应用的挑战 随着生活品质的不断提升,人们对于健康问题也越来越重视。作为一家以“AI重塑健康与美”为使命的AI数字健康解决方案提供商&a…

langchain学习总结

大模型开发遇到的问题及langchain框架学习 背景: 1、微场景间跳转问题,无法实现微场景随意穿插 2、大模型幻读(推荐不存在的产品、自己发挥) 3、知识库检索,语义匹配效果较差,匹配出的结果和客户表述的…

解决指南:如何应对错误代码 0x80070643

在使用Windows操作系统过程中,用户可能会遭遇各种错误代码,其中错误 0x80070643是比较常见的一种。这个错误通常在安装更新或某些软件时发生,尤其是在微软的Windows Defender或其他Microsoft安全产品以及.NET Framework更新过程中更为常见。本…

动画重定向——当给一个人物模型用别人物的动画时,会遇到人物与动画不匹配问题,怎么解决呢?

每日一句:实践出真知,试错方确信 目录 最开始我想的原因! 分析一下动画相关参数 Animator组件参数详解: 人物模型的导入设置参数: Skinned Mesh Renderer组件详解: Skinned Mesh Renderer工作原理 设置Skinned …

【吴恩达深度学习笔记系列】Logistic Regression 【理论】

Binary Classification: Logistic Regression: y ^ σ ( w T x b ) \hat{y}\sigma{(w^T xb)} y^​σ(wTxb) using sigmoid function σ 1 1 e − z \sigma \frac{1}{1e^{-z}} σ1e−z1​. 【torch.sigmoid(x)】 Sigmoid ( x ) 1 1 e − x \text{Sigmoid}(x)\frac{1}{…

nginx优势以及应用场景,编译安装和nginx

一. Nginx是什么? 1. Nginx概述 高性能、轻量级Web服务软件系统资源消耗低对HTTP并发连接的处理能力高单台物理服务器可支持30,000~50,000个并发请求Nginx(发音同 “engine x”)是一个高性能的反向代理和Web服务器软件&#xff0c…

【05】从0到1构建AI生成思维导图应用 -- 前端交互实现

【05】从0到1构建AI生成思维导图应用 – 前端交互实现 大家好!最近自己做了一个完全免费的AI生成思维导图的网站,支持下载,编辑和对接微信公众号,可以在这里体验:https://lt2mind.zeabur.app/ 上一章:http…