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

网页制作用哪个软件宁波seo的公司联系方式

网页制作用哪个软件,宁波seo的公司联系方式,在线注册公司营业执照,广州短视频seo哪家好1. 引言"Do not communicate by sharing memory; instead, share memory by communicating." (不要通过共享内存来通信,而应通过通信来共享内存。) 这是 Go 语言并发设计的核心哲学。而 channel 正是实现这一哲学的核心工具。Channel 为 Goroutine 之间的…

1. 引言

"Do not communicate by sharing memory; instead, share memory by communicating." (不要通过共享内存来通信,而应通过通信来共享内存。) 这是 Go 语言并发设计的核心哲学。而 channel 正是实现这一哲学的核心工具。

Channel 为 Goroutine 之间的通信提供了安全的、同步的机制。它究竟是如何在底层保证并发安全和实现阻塞/非阻塞操作的?本文将深入其源码,揭示 channel 的内部奥秘。

2. Channel 的核心数据结构

在 Go 的 runtime/chan.go 源码中,channel 的底层实现是一个名为 hchan 的结构体。其核心字段如下(有简化):

// src/runtime/chan.go
type hchan struct {qcount   uint           // channel 中当前的元素个数dataqsiz uint           // channel 的容量(环形队列的大小)buf      unsafe.Pointer // 指向容量大小为 dataqsiz 的环形队列elemsize uint16         // channel 中元素的大小closed   uint32         // 标记 channel 是否关闭sendx uint // 环形队列的发送索引recvx uint // 环形队列的接收索引recvq waitq // 等待接收的 goroutine 队列 (sudog 链表)sendq waitq // 等待发送的 goroutine 队列 (sudog 链表)lock mutex // 保证 channel 操作的原子性
}type waitq struct {first *sudoglast  *sudog
}

核心组件解析

  • buf (环形队列): 对于带缓冲的 channel,buf 是一个环形队列,用于存储元素。发送和接收操作通过移动 sendxrecvx 索引来完成。

  • lock (互斥锁): channel 的所有操作(发送、接收、关闭)都必须先获取这个锁,这保证了其并发安全性。

  • sendqrecvq (等待队列): 这是 channel 实现阻塞和唤醒的关键。

    • 当一个 goroutine 尝试向一个已满的 channel 发送数据时,它会被打包成一个 sudog(goroutine 在运行时的表示)并加入到 sendq 等待队列中,然后该 goroutine 会被挂起(park)

    • 当一个 goroutine 尝试从一个空的 channel 接收数据时,它也会被加入到 recvq 等待队列中并被挂起。

3. Channel 的操作原理
3.1 发送操作 (ch <- data)
  1. 加锁lock.Lock()

  2. 检查 closed 标志:如果 channel 已关闭,直接 panic

  3. 检查 recvq:如果接收等待队列 recvq 不为空,说明有 goroutine 正在等待接收数据。

    • 这是无缓冲 channel空缓冲 channel的接收者。

    • 直接将要发送的数据拷贝给等待的 goroutine。

    • 唤醒(gounpark)该 goroutine。

    • 解锁,发送完成。

  4. 检查 buf:如果 buf (环形队列) 还有空间 (qcount < dataqsiz)。

    • 将数据拷贝到 bufsendx 位置。

    • sendx 索引递增。

    • qcount 递增。

    • 解锁,发送完成。

  5. 阻塞发送:如果 recvq 为空且 buf 已满。

    • 将当前 goroutine 和要发送的数据打包成 sudog

    • 加入 sendq 发送等待队列。

    • 挂起当前 goroutine (gopark),并解锁。goroutine 会在此等待,直到有接收者将其唤醒。

3.2 接收操作 (<-ch)
  1. 加锁lock.Lock()

  2. 检查 sendq:如果发送等待队列 sendq 不为空。

    • 这通常发生在无缓冲 channel满缓冲 channel

    • sendq 中取出一个等待的 goroutine。

    • 如果 buf 为空,直接从该 goroutine 中取出数据。

    • 如果 buf 已满,先将 buf 的队首元素取出作为返回值,然后将等待 goroutine 的数据存入 buf 队尾。

    • 唤醒该发送 goroutine。

    • 解锁,接收完成。

  3. 检查 buf:如果 buf 中有数据 (qcount > 0)。

    • bufrecvx 位置取出数据。

    • recvx 索引递增。

    • qcount 递减。

    • 解锁,接收完成。

  4. 检查 closed 标志:如果 channel 已关闭且 buf 为空,立即返回元素类型的零值。

  5. 阻塞接收:如果上述条件都不满足。

    • 将当前 goroutine 打包成 sudog

    • 加入 recvq 接收等待队列。

    • 挂起当前 goroutine (gopark) 并解锁

4. select 的实现

select 语句的实现更为复杂,它会将涉及到的所有 case 构建成一个 scase 数组,然后通过 selectgo 函数执行以下逻辑:

  1. 随机轮询:打乱 scase 数组的顺序,防止优先级问题。

  2. 非阻塞检查:遍历所有 case,检查是否有任何一个 channel 可以立即进行非阻塞的发送或接收。如果有,则执行该操作并返回。

  3. 阻塞等待:如果所有 case 都无法立即完成,将当前 goroutine 加入到所有相关 channel 的等待队列中,然后挂起。

  4. 唤醒:当任何一个 channel 的操作条件满足时(例如,有数据被发送进来),对应的 channel 会唤醒这个等待的 goroutine。goroutine 被唤醒后,会完成相应的 case 操作。

5. 总结

Go channel 的底层是一个由互斥锁、环形队列和两个等待队列(sudog 链表)组成的精密结构。正是通过 lock 保证了并发安全,通过 sendqrecvq 配合调度器的 goparkgounpark,实现了 goroutine 之间的同步与通信。理解这一机制,有助于我们更深刻地运用 Go 的并发能力。

http://www.dtcms.com/a/550873.html

相关文章:

  • 如何理解不同行业AI决策系统的功能差异?
  • 长沙英文网站建设公司郑州大型网站公司
  • 建设部网站村镇建设口碑营销的产品
  • 网站建设网站模版广东省建设工程交易中心
  • 深圳网站建设培训班本科自考有哪些科目
  • RHEL 9.6 从源码安装 Open vSwitch 完整指南
  • 域名跟空间都有了怎么做网站网站的思维导图怎么做
  • 高端建站用什么软件菏泽 做网站 多少钱
  • 网站导航页设计标识设计公司排名
  • 【符号论】群的概念与五行关系的循环群结构
  • 宜兴网站建设价格信息做海报的素材那个网站比较好
  • 网站开发用到的技术上海网站建设上海
  • 昆山高端网站建设咨询设计公司职位
  • 你问GeeLark答 QA 第8章
  • 南京360推广 网站建设网页视频加速器
  • 有谁知道网站优化怎么做南宁网站建设信息推荐
  • 永川区网站建设名词解释搜索引擎优化
  • 点云深度学习:KPFCNN(Kernel Point Convolutional Neural Network)
  • Rust:类型 impl
  • STM32项目分享:避障小车设计
  • 从密集到稀疏:InfLLM-V2 如何实现零参数开销的长文本高效处理
  • 网站推广平台排行如何免费建立官方网站
  • 基于MATLAB的Copula函数实现合集
  • p2p贷款网站建设建设网站需要的人员及资金
  • 佛山市网站建设分站哪家好开发公司物业移交物业协议
  • wordpress 网站导航龙岩食品有限公司
  • 有网站做点什么好wordpress多媒体插件
  • 网站建设得缺点自媒体营销推广
  • 李红波先生与EDT过滤器(替代ERF1150X FILTER)的故事
  • 提示词构成