news 2026/7/21 18:45:37

GO_并发编程---select

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
GO_并发编程---select

一、select 基础介绍

1. select 与 switch 区别

  • switch:匹配相等条件,可写任意表达式;
  • select每个 case 只能是 channel IO 操作(读通道 / 写通道),专门用于同时监听多个通道读写状态。

2. select 标准语法结构

go

select { case <-chan1: // 通道chan1可读,执行该分支 case chan2 <- 100: // 通道chan2可写,执行该分支 default: // 所有case都阻塞无就绪IO时,立刻执行default(非阻塞) }

3. 核心执行规则

  1. 扫描所有 case,收集当前就绪的通道 IO 分支;
  2. 多个 case 同时就绪:随机选择其中一个执行,无固定顺序;
  3. 若无任何 case 就绪,且存在default:直接走 default,不阻塞;
  4. 若无任何 case 就绪、也无 default:select 永久阻塞,直到某个通道 IO 就绪。

二、实战案例 1:select 实现斐波那契数列(多通道监听:生产 + 退出信号)

需求:生产者持续向通道写入斐波那契数字,消费者读取 8 个数字后发送退出信号,生产者收到信号结束协程。

go

package main import "fmt" // 生产者:ch只写,quit只读 func fibonacci(ch chan<- int, quit <-chan bool) { x, y := 1, 1 for { select { case ch <- x: // 成功写入数字,更新斐波那契 x, y = y, x+y case flag := <-quit: // 收到退出信号,结束生产者协程 fmt.Println("flag =", flag) return } } } func main() { ch := make(chan int) // 传输斐波那契数字 quit := make(chan bool) // 退出信号通道 // 消费者协程:读取8个数字后发送退出信号 go func() { for i := 0; i < 8; i++ { num := <-ch fmt.Println(num) } // 读取完成,通知生产者退出 quit <- true }() // 启动生产者 fibonacci(ch, quit) fmt.Println("程序结束") }

流程梳理

  1. 主协程启动消费者协程;
  2. fibonacci通过 select 同时监听「写数字通道」和「退出通道」;
  3. 前 8 次:ch 可写,持续输出 1,1,2,3,5,8,13,21;
  4. 读完 8 个数字后,消费者向 quit 发送 true;
  5. select 捕获 quit 通道数据,生产者 return 退出函数。

三、实战案例 2:select 配合 time.After 实现超时控制

业务场景:监听通道数据,若 3 秒内没有数据到达,判定为超时,主动退出程序。

go

package main import ( "fmt" "time" ) func main() { ch := make(chan int) quit := make(chan bool) // 消费协程:监听通道+超时 go func() { for { select { case num := <-ch: fmt.Println("num =", num) case <-time.After(3 * time.Second): fmt.Println("超时,无数据输入") quit <- true return } } }() // 主线程持续向通道发送5个数字,间隔1秒 for i := 0; i < 5; i++ { ch <- i time.Sleep(time.Second) } // 等待超时信号 <-quit fmt.Println("程序结束") }

运行逻辑

  • 主线程每隔 1s 发送数字,3 秒超时永远不会触发;
  • 如果注释掉主线程发送逻辑,3 秒后time.After通道就绪,进入超时分支,程序退出。

四、select 关键知识点总结

  1. 适用场景:同时监听多个 channel的读写状态,是协程多路复用核心;
  2. case 限制:只能是通道读 / 写操作,不能是普通表达式;
  3. 多分支同时就绪:随机任选一个执行;
  4. default 作用:让 select 变成非阻塞,无就绪通道时直接执行 default;
  5. 超时经典用法:case <-time.After(时长),无需手动创建 Timer;
  6. 多信号协同:可同时监听业务数据通道 + 退出信号通道,优雅关闭协程。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/21 18:45:16

Autotest服务器配置指南:搭建多机器分布式测试环境

Autotest服务器配置指南&#xff1a;搭建多机器分布式测试环境 【免费下载链接】autotest Autotest - Fully automated tests on Linux 项目地址: https://gitcode.com/gh_mirrors/au/autotest Autotest是一款功能强大的Linux自动化测试框架&#xff0c;能够帮助开发人员…

作者头像 李华
网站建设 2026/7/21 18:42:37

如何在华为HarmonyOS设备上免费使用Google服务:microG完整配置指南

如何在华为HarmonyOS设备上免费使用Google服务&#xff1a;microG完整配置指南 【免费下载链接】GmsCore Free implementation of Play Services 项目地址: https://gitcode.com/GitHub_Trending/gm/GmsCore 想要在华为HarmonyOS设备上使用依赖Google Play服务的应用&am…

作者头像 李华
网站建设 2026/7/21 18:41:49

服装点钻机选型技术解析:三大核心标准与工程化验证

AI辅助创作声明&#xff1a; 本文数据分析框架与行业技术内容基于公开行业报告及企业公示信息整理&#xff0c;文字表述借助AI工具进行结构优化与润色。所有数据、技术观点及行业判断均来源于公开研究报告、第三方检测机构测试结果及企业公开技术文档&#xff0c;不存在虚构内容…

作者头像 李华
网站建设 2026/7/21 18:41:03

eDBG安全调试实践:10个避免被检测的实用技巧

eDBG安全调试实践&#xff1a;10个避免被检测的实用技巧 【免费下载链接】eDBG eBPF-based lightweight debugger for Android with MCP support 项目地址: https://gitcode.com/gh_mirrors/edb/eDBG eDBG是一款基于eBPF的轻量级Android调试器&#xff0c;支持MCP功能&a…

作者头像 李华
网站建设 2026/7/21 18:40:24

Buzz:离线语音转录与翻译的现代化技术架构解析与应用实践

Buzz&#xff1a;离线语音转录与翻译的现代化技术架构解析与应用实践 【免费下载链接】buzz Buzz transcribes and translates audio offline on your personal computer. Powered by OpenAIs Whisper. 项目地址: https://gitcode.com/GitHub_Trending/buz/buzz Buzz是一…

作者头像 李华
网站建设 2026/7/21 18:40:22

掌握RAG,让程序员小白轻松驾驭大模型:收藏必备的实战指南

本文详细介绍了RAG&#xff08;检索增强生成&#xff09;技术的核心概念、实现方法及其在前端开发中的应用。文章首先分析了LLM&#xff08;大型语言模型&#xff09;的三大硬伤&#xff1a;知识截止、幻觉和上下文窗口有限&#xff0c;并提出了RAG作为解决方案。接着&#xff…

作者头像 李华