0

0

解析Golang中的Channel在不同协程间的传递 Go语言引用语义与内存

P粉602998670

P粉602998670

发布时间:2026-03-12 11:07:03

|

473人浏览过

|

来源于php中文网

原创

能,channel是引用类型,传参时传递的是底层hchan指针,多个goroutine共享同一队列和锁;需由唯一发送方关闭且只关一次,接收方须用v, ok :=判断是否关闭。

解析golang中的channel在不同协程间的传递 go语言引用语义与内存

Go 中 channel 能不能像普通变量一样传给其他 goroutine?

能,但必须理解它传的是“引用”还是“值”——channel 类型本身是引用类型,赋值或传参时传递的是底层 hchan 结构体的指针,不是拷贝。这意味着多个 goroutine 操作同一个 channel 实例,本质是在共享同一套发送/接收队列和锁。

常见错误现象:panic: send on closed channel 或死锁,往往是因为多个 goroutine 误以为自己“拥有”该 channel,擅自 close();或者一个 goroutine 关闭后,另一个还在尝试接收却没做判断。

  • 只要不显式 close(),多个 goroutine 安全地读写同一 channel 是 Go 的设计前提
  • 关闭操作应由“唯一负责发送”的 goroutine 执行,且只关一次
  • 接收方务必用 v, ok := 形式判断是否已关闭,不能只依赖 <code>

把 channel 当函数参数传进去,会不会意外复制?

不会。Go 中所有内置 channel 类型(chan Tchan、<code>)都是引用类型,传参、赋值、字段存储都只是复制指针。你可以把它类比为 <code>*os.File:改的是同一片内存里的状态。

使用场景:常用于构造“生产者-消费者”模式,比如启动 worker goroutine 时把 chan int 作为参数传入:

立即学习go语言免费学习笔记(深入)”;

go worker(ch)

这里 ch 是原变量,worker 收到的是完全等价的引用,后续对它的读写直接影响原始 channel 状态。

智简简历
智简简历

免费AI简历制作工具,智能生成、可视化编辑、多格式导出。

下载
  • 注意方向性:传 chan 进去,函数体内只能发不能收;传 <code> 则只能收不能发
  • 方向转换需显式类型断言或重新声明,不能直接赋值(如 chan intchan 合法,反过来不合法)
  • 结构体字段存 channel 也没问题,但要注意生命周期:若结构体被多次复制,channel 字段仍指向同一底层对象

为什么往 channel 发数据有时卡住,有时 panic?

卡住(goroutine 阻塞)和 panic(运行时错误)是两类不同问题,根源都在 channel 的状态和操作合法性上。

常见错误现象:

  • nil channel 发送或接收 → 永久阻塞(因为 nil channel 永远不会就绪)
  • 向已关闭的 channel 发送 → panic: send on closed channel
  • 从已关闭且无缓冲的 channel 接收完所有数据后继续接收 → 不 panic,返回零值 + ok=false

性能影响:阻塞本身不消耗 CPU,但会让 goroutine 挂起等待调度器唤醒;而 panic 会终止当前 goroutine,若未 recover 可能导致整个程序崩溃。

  • 初始化 channel 必须用 make(chan T),避免传 nil
  • 不要在多个 goroutine 中并发调用 close(),哪怕加了判断也容易竞态
  • 如果需要“安全关闭”,推荐用 sync.Once 包一层,或用额外的 done chan struct{} 控制生命周期

channel 和指针在内存模型里到底谁更“轻”?

channel 更重。一个 chan int 变量本身只占 8 字节(64 位系统下指针大小),但它的底层 hchan 结构体包含互斥锁、环形缓冲区指针、长度计数器等,实际分配在堆上,大小远超指针。

对比:一个 *int 就是纯指针,8 字节,不带任何同步逻辑;而 chan int 是带锁、带队列、带条件变量的完整并发原语。

  • 别为了“省内存”把小数据塞进 channel 代替指针传递——除非你明确需要同步语义
  • channel 的开销主要在首次 make 分配和每次发送/接收的锁竞争上,不是变量本身
  • 如果只是想让 goroutine 共享某个值,用指针 + sync.Mutexatomic 更轻量;channel 应用于“解耦通信”而非“共享状态”

真正容易被忽略的是:channel 的关闭行为不可逆,且对所有持有该 channel 的 goroutine 立即可见。这点比指针复杂得多,也危险得多。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

210

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

247

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

356

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

214

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

409

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

490

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

201

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

1458

2025.06.17

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 6.1万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号