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

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道有缓冲通道,它们在并发编程中各具特点和应用场景。


一、通道的基本分类

类型定义形式特点
无缓冲通道make(chan T)发送和接收都必须准备好,操作是同步的
有缓冲通道make(chan T, size)有固定长度缓冲区,操作是异步的(缓冲区未满/未空)

二、无缓冲通道:同步通信

无缓冲通道要求发送和接收必须同步配对,否则操作将阻塞。

示例:
func main() {ch := make(chan int)go func() {fmt.Println("发送前")ch <- 10 // 阻塞,直到主协程接收fmt.Println("发送后")}()time.Sleep(1 * time.Second)fmt.Println("准备接收")val := <-chfmt.Println("接收值:", val)
}
输出:
发送前
准备接收
接收值:10
发送后

适用场景:

  • • 精确同步:保证发送和接收顺序一致
  • • 控制并发节奏
  • • 实现信号通知机制(如任务完成)

三、有缓冲通道:异步通信

有缓冲通道内部维护一个队列,允许发送操作在缓冲区未满时立即返回,不阻塞。

示例:
func main() {ch := make(chan string, 2)ch <- "Go"ch <- "语言"// ch <- "并发" // 会阻塞,因为缓冲区已满fmt.Println(<-ch)fmt.Println(<-ch)
}
输出:
Go
语言
特点:
  • • 发送阻塞发生在缓冲区满时
  • • 接收阻塞发生在缓冲区空时
  • • 更适合高吞吐、解耦生产者和消费者速率的场景

适用场景:

  • • 任务队列
  • • 缓冲池
  • • 生产者-消费者模型

四、行为差异对比

操作行为无缓冲通道有缓冲通道(缓冲区未满)
ch <- val阻塞直到接收完成立即发送,缓冲区+1
<-ch阻塞直到有发送值从缓冲区读取
close(ch)可关闭同样适用

五、死锁风险

无缓冲通道如果没有接收者,将会造成死锁:

func main() {ch := make(chan int)ch <- 1 // 无人接收,将死锁
}

编译不会报错,运行时直接 panic:

fatal error: all goroutines are asleep - deadlock!

六、建议使用原则

  • • 无缓冲通道
    • • 用于事件通知、同步操作(如信号触发)
    • • 更容易暴露并发问题,适合教学或调试时使用
  • • 有缓冲通道
    • • 用于任务派发、流水线设计
    • • 缓冲大小需根据业务负载合理设置

七、小结

比较维度无缓冲通道有缓冲通道
通信模式同步通信异步通信
是否阻塞发送是(需等待接收)否(缓冲区未满时)
是否阻塞接收是(需等待发送)否(缓冲区非空时)
适合场景精确同步、信号传递解耦读写、任务队列、高并发系统

通道的正确选择与使用,是实现高效并发的基础。



文章转载自:

http://YQWSv1S6.bpmnx.cn
http://Nhlf8Tzb.bpmnx.cn
http://U4K0N3Hc.bpmnx.cn
http://tjiROamE.bpmnx.cn
http://LDGMoEcU.bpmnx.cn
http://e7HTrpH4.bpmnx.cn
http://SElN0YUp.bpmnx.cn
http://vXK7Tszg.bpmnx.cn
http://mXVmb6nF.bpmnx.cn
http://tAhoRjgj.bpmnx.cn
http://54cymt6y.bpmnx.cn
http://emzomnpD.bpmnx.cn
http://bPh3j3p9.bpmnx.cn
http://WXK17WVR.bpmnx.cn
http://dfaQzzVl.bpmnx.cn
http://rf9Rzu2F.bpmnx.cn
http://jKstOxCh.bpmnx.cn
http://lwJ0k15t.bpmnx.cn
http://MGUiuF63.bpmnx.cn
http://r3iIpx3r.bpmnx.cn
http://2x5pH9Bf.bpmnx.cn
http://B41RnibZ.bpmnx.cn
http://EYXBzoVr.bpmnx.cn
http://FN2hlGNU.bpmnx.cn
http://wXENS2DW.bpmnx.cn
http://itovK5X8.bpmnx.cn
http://genCp1RN.bpmnx.cn
http://g866lun1.bpmnx.cn
http://HyDvX6xq.bpmnx.cn
http://7UwN5F9v.bpmnx.cn
http://www.dtcms.com/a/236249.html

相关文章:

  • VScode 使用 git 提交数据到指定库的完整指南
  • 【Fiddler工具判断前后端Bug】
  • 飞牛云一键设置动态域名+ipv6内网直通访问内网的ssh服务-家庭云计算专家
  • Linux下VSCode开发环境配置(LSP)
  • 阿里云ACP云计算备考笔记 (4)——企业应用服务
  • 客户端和服务器已成功建立 TCP 连接【输出解析】
  • WPF八大法则:告别模态窗口卡顿
  • 使用有限计算实现视频生成模型的高效训练
  • 安全访问家中 Linux 服务器的远程方案 —— 专为单用户场景设计
  • uniapp 对接腾讯云IM群公告功能
  • wpf的converter
  • 手机号在网状态查询接口如何用PHP实现调用?
  • Cisco Packer Tracer 综合实验
  • 使用Python和Flask构建简单的机器学习API
  • 基于物联网设计的智慧家庭健康医疗系统
  • 数据库系统概论(十七)超详细讲解数据库规范化与五大范式(从函数依赖到多值依赖,再到五大范式,附带例题,表格,知识图谱对比带你一步步掌握)
  • 大模型Agent智能体介绍和应用场景
  • MySql数据库入门到精通——关系数据库标准语言SQL
  • MySQL SQL 优化:从 INSERT 到 LIMIT 的实战与原理
  • 杭州瑞盟 MS35774/MS35774A 低噪声256细分微步进电机驱动,用于空调风门电机驱动,香薰电机驱动
  • 微信小程序带参分享、链接功能
  • ThingsCloud事物云平台搭建-微信小程序
  • 快速上手Linux全局搜索正则表达式(grep)
  • 文档极速转换器 - 免费批量Word转PDF工具
  • 线性代数小述(二之前)
  • 1.4 Node.js 的 TCP 和 UDP
  • 【LLM-Agent】智能体的记忆缓存设计
  • Python实例题:Python计算线性代数
  • C++--list的使用及其模拟实现
  • 51单片机基础部分——矩阵按键检测