发布时间:2026/7/20 23:58:27
GO_并发编程---channel 前置回顾Go 并发核心设计理念不要通过共享内存来通信而要通过通信来共享内存goroutine之间数据同步、数据交互统一依靠channel实现解决多协程资源竞争问题。一、Channel 基础概念作用实现多个 goroutine 同步协程之间安全共享、传递数据底层理解可以把 channel 看作一根管道 / 水管两端分别对应发送、接收无缓存管道一端没就绪另一端会阻塞有缓存管道缓冲区存数据缓冲区满 / 空时发生阻塞。传递特性channel 本身是地址传递引用类型不是值传递。二、Channel 创建语法使用内置函数make创建分两种go// 1. 无缓冲通道容量为0 ch : make(chan 数据类型) ch : make(chan int, 0) // 2. 有缓冲通道capacity代表缓冲区最大存储数量 ch : make(chan string, 5)三、Channel 收发操作符--是通道专属操作符四种常用写法go// 1. 发送数据把value写入通道 channel - value // 2. 接收数据直接丢弃不保存 -channel // 3. 接收数据赋值给变量x x : -channel // 4. 接收判断通道状态重点 // oktrue通道未关闭正常读到数据 // okfalse通道已关闭无数据可读 x, ok : -channel阻塞规则通道无数据可读时接收操作阻塞无缓冲通道、缓冲区已满的有缓冲通道发送操作阻塞。四、无缓冲 Channel同步通道定义创建时容量为 0缓冲区无法存储任何数据。核心特性发送和接收必须同时就绪否则阻塞先执行发送ch - val阻塞等待其他协程接收先执行接收-ch阻塞等待其他协程发送只有收发双方同时到位数据才会完成传递协程继续向下执行。示例 1利用无缓冲通道实现协程同步gopackage main import fmt // 全局通道 var ch make(chan int) func Printer(str string) { for _, v : range str { fmt.Print(string(v)) } fmt.Println() } func person1() { Printer(hello) ch - 666 // 发送数据通知person1执行完毕 } func person2() { -ch // 阻塞等待收到数据后才执行打印 Printer(world) } func main() { go person1() go person2() for {} // 阻塞主协程防止程序退出 }执行顺序固定hello先打印再打印world实现协程同步。示例 2无缓冲通道完整读写演示gopackage main import ( fmt time ) func main() { // 无缓冲通道 ch : make(chan int, 0) fmt.Printf(len(ch)%d, cap(ch)%d\n, len(ch), cap(ch)) // 子协程发送数据 go func() { for i : 0; i 3; i { fmt.Println(子协程 i , i) ch - i // 无缓冲会阻塞等待主协程读取 } }() time.Sleep(2 * time.Second) // 主协程循环读取 for i : 0; i 3; i { num : -ch fmt.Println(num , num) } }五、有缓冲 Channel异步通道定义创建时指定容量 capacity内部自带缓冲区可以预先存储多条数据。go// 缓冲区最多存3个int ch : make(chan int, 3)核心特性缓冲区未满发送数据不会阻塞直接存入缓冲区缓冲区已满发送操作阻塞等待其他协程读取腾出空间缓冲区有数据接收操作直接读取不阻塞缓冲区为空接收操作阻塞。示例有缓冲通道读写gopackage main import ( fmt time ) func main() { ch : make(chan int, 3) go func() { for i : 0; i 3; i { ch - i fmt.Printf(子协程[%d] len(ch)%d, cap(ch)3\n, i, len(ch)) } }() time.Sleep(2 * time.Second) for i : 0; i 3; i { num : -ch fmt.Println(num , num) } }六、关闭 Channel close ()使用场景确认后续不会再向通道发送数据时调用close(ch)关闭通道。重要规则关闭后的通道禁止发送数据发送会直接 panic 崩溃通道关闭后缓冲区剩余数据仍可正常读取缓冲区数据全部读完后再次读取会返回okfalse。方式 1if 判断 ok 读取通道gopackage main import fmt func main() { ch : make(chan int) go func() { for i : 0; i 5; i { ch - i } close(ch) // 写完数据关闭通道 }() for { num, ok : -ch if ok true { fmt.Println(num , num) } else { fmt.Println(通道已关闭退出循环) break } } }方式 2range 遍历通道推荐for range会自动循环读取通道数据通道关闭后自动结束循环无需手动判断 okgofor num : range ch { fmt.Println(num , num) }七、单向 Channel只读 / 只写通道语法区分箭头方向go// 双向通道可读可写默认 var ch chan int // 只写通道chan-只能发送数据不能读取 var writeCh chan- float64 // 只读通道-chan只能读取数据不能发送 var readCh -chan int转换规则双向通道可以隐式转为单向通道单向通道不能转回双向通道编译报错。gopackage main import fmt func main() { ch : make(chan int) // 双向通道 // 双向转单向合法 var writeCh chan- int ch var readCh -chan int ch writeCh - 666 // 只写通道执行发送 -readCh // 只读通道执行接收 // 错误单向无法转回双向 // var ch2 chan int writeCh }实战场景生产者消费者模型单向通道用于函数参数约束规范函数行为代码可读性更高producer 生产者只写通道负责生产数据写入管道consumer 消费者只读通道负责读取管道数据gopackage main import fmt // 生产者只写通道 func producer(out chan- int) { for i : 0; i 10; i { out - i * i } close(out) // 生产完成关闭通道 } // 消费者只读通道 func consumer(in -chan int) { for num : range in { fmt.Println(num , num) } } func main() { ch : make(chan int) go producer(ch) // 开启生产者协程 consumer(ch) // 主线程消费 }八、Channel 核心复习总结Go 并发核心思想通信共享内存channel 是 goroutine 通信载体channel 是引用类型分无缓冲、有缓冲两类无缓冲通道收发必须成对出现天然实现同步有缓冲通道异步存储数据close()关闭通道后不能发送但剩余数据可读取range 简化通道循环读取单向通道约束读写权限常用于生产者消费者模型阻塞逻辑无数据读阻塞、缓冲区满写阻塞。

相关新闻

2026/7/20 23:53:27

AM275x CBASS防火墙配置实战:权限控制与地址范围详解

1. CBASS防火墙核心概念与AM275x安全架构解析在复杂的嵌入式系统,尤其是像TI AM275x这样的高性能信号处理器中,硬件安全不再是“锦上添花”的选项,而是系统稳定运行的基石。我处理过不少因为内存访问越界或权限配置不当导致的系统崩溃、数据泄…

2026/7/20 23:53:27

.NET开发者学习Python:互补优势与实战指南

1. 为什么.NET开发者需要学习Python?作为一名有十年经验的.NET全栈工程师,我最初对Python也是持怀疑态度的——直到我在实际项目中被迫使用它解决了一个C#难以处理的问题。Python在数据科学、机器学习、快速原型开发等领域的生态优势,正在让它…

2026/7/21 13:00:42

终极GIMP界面美化指南:5分钟让免费软件用出Photoshop的感觉

终极GIMP界面美化指南:5分钟让免费软件用出Photoshop的感觉 【免费下载链接】PhotoGIMP A Patch for GIMP 3 for Photoshop Users 项目地址: https://gitcode.com/GitHub_Trending/ph/PhotoGIMP 还在为GIMP的复杂界面而烦恼吗?PhotoGIMP为您带来革…

2026/7/21 13:00:41

Unity与Vuforia打造多图识别AR应用:从开发到安卓APK打包全流程

1. 项目概述:从创意到可触达的AR体验在移动应用开发领域,增强现实(AR)技术早已不是遥不可及的概念。但很多开发者,尤其是刚入门的爱好者,常常卡在“从Demo到产品”的最后一公里。你或许已经能用Vuforia SDK…

2026/7/21 13:00:41

Jenkins与Docker实现高效CI/CD流水线实践

1. 项目概述 在当今的软件开发领域,持续集成和持续交付(CI/CD)已经成为提升团队效率的标配。作为一名经历过无数次手动部署痛苦的老兵,我深刻体会到自动化部署的价值。本文将分享如何利用Jenkins和Docker这对黄金组合搭建完整的CI/CD流水线。 这个方案特…

2026/7/21 13:00:41

B站视频下载器完整指南:5分钟掌握大会员4K视频离线观看

B站视频下载器完整指南:5分钟掌握大会员4K视频离线观看 【免费下载链接】bilibili-downloader B站视频下载,支持下载大会员清晰度4K,持续更新中 项目地址: https://gitcode.com/gh_mirrors/bil/bilibili-downloader 你是否曾经因为网络…

2026/7/21 13:00:41

5分钟掌握:如何轻松获取国家中小学智慧教育平台电子课本PDF文件

5分钟掌握:如何轻松获取国家中小学智慧教育平台电子课本PDF文件 【免费下载链接】tchMaterial-parser 国家中小学智慧教育平台 电子课本下载工具,帮助您从智慧教育平台中获取电子课本的 PDF 文件网址并进行下载,让您更方便地获取课本内容。 …

2026/7/20 6:33:00

Unity与Python本地通信:基于Flask的跨语言数据交换实战

1. 项目概述:为什么我们需要一个本地通信服务器?在游戏开发、数字孪生、仿真训练等众多领域,Unity作为强大的实时3D内容创作平台,其核心逻辑通常由C#驱动。然而,当我们需要进行复杂的数据分析、机器学习推理、科学计算…

2026/7/21 0:08:52

华为OD机试 新系统真题 【酒店服务记录分析】

酒店服务记录分析(C++/Go/C/Js/Java/Py)题解 华为OD机试 新系统真题 华为OD上机考试 新系统真题 7月19号 100分题型 华为OD机试新系统真题目录点击查看: 华为OD机试新系统真题题库目录|机考题库 + 算法考点详解 题目内容 你是某连锁酒店的数据分析师,酒店每天都会用一串编…

2026/7/21 0:08:52

华为OD机试 新系统真题 【小明的顺风车】

小明的顺风车(C++/Go/C/Js/JAVA/Py)题解 华为OD机试新系统真题 华为OD上机考试新系统真题 7月19号 200分题型 华为OD机试新系统真题目录点击查看: 华为OD机试新系统真题题库目录|机考题库 + 算法考点详解 题目内容 小明自驾回家,为节省旅途成本,决定在网上挂出顺风车服务…

2026/7/20 19:08:28

3个高效策略:快速掌握Axure中文界面配置

3个高效策略:快速掌握Axure中文界面配置 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的英文界面感…