Go 的 select 实战:超时、非阻塞收发与优雅退出的三个套路
📅 2026/7/24 16:23:05
👁️ 次浏览
Go 的 select 实战:超时、非阻塞收发与优雅退出的三个套路很多人学 Go 并发,select只会写「从多个 channel 里随便读一个」。但实战里select真正好用的是三个套路:给操作加超时、非阻塞地试探 channel、以及优雅关闭 goroutine。这三个不掌握,写出来的并发代码要么卡死,要么泄漏 goroutine。这篇一个一个过。套路一:给 channel 操作加超时朴素写法:直接从 channel 读,读不到就永远阻塞。// 危险:worker 出问题没往 ch 写,这里会永久卡住funcwaitResult(ch-chanint)int{return-ch}生产环境这种代码就是定时炸弹——上游一旦不响应,这个 goroutine 就永远挂在这里,连带上游的资源也释放不掉。正确做法是用select配一个time.After:importtimefuncwaitResult(ch-chanint)(int,error){select{casev:-ch:returnv,nilcase-time.After(2*time.Second):// 超过 2 秒没结果就返回错误,不再干等return0,fmt.Errorf(timeout waiting for result)}}time.After(d)返回一个 channel,d时间后会往里塞一个值。select会同时监听结果 channel 和这个定时 channel,哪个先来走哪个。一个坑:time.After在超时前不会被 GC 回收。如果你在一个高频循环里用它,会短暂堆积大量 Timer。循环内的超时应改用time.NewTimer并手动Stop:funcwaitResultLoop(ch-chanint){timer:time.NewTimer(2*time.Second)defertimer.Stop()// 用完及时释放,避免 Timer 堆积select{casev:-ch:fmt.Println(v)case-timer.C:fmt.Println(timeout)}}套路二:非阻塞收发有时你不想等,只想「试一下,能读就读,不能读就算了」。关键是给select加一个default分支——只要有default,select就永远不会阻塞。// 非阻塞读:channel 里有数据就拿,没有就走 defaultfunctryRead(ch-chanint){select{casev:-ch:fmt.Println(got:,v)default:fmt.Println(nothing ready, skip)}}// 非阻塞写:channel 满了就丢弃,不阻塞生产者functrySend(chchan-int,vint)bool{select{casech-v:returntruedefault:returnfalse// 缓冲满了,主动丢弃(比如做限流/降级)}}非阻塞写在实战里特别有用:比如做一个「有界的事件上报队列」,队列满了宁可丢事件也不能阻塞主流程,trySend就是标准写法。套路三:优雅退出 goroutine启动了 goroutine 却没法通知它退出,是 Go 里最常见的泄漏源。标准解法是用一个donechannel(或context)配select:funcworker(jobs-chanint,done-chanstruct{}){for{select{casejob:-jobs:process(job)case-done:// 收到退出信号,清理后返回,goroutine 正常结束fmt.Println(worker exiting)return}}}funcmain(){jobs:make(chanint)done:make(chanstruct{})goworker(jobs,done)jobs-1jobs-2close(done)// 关闭 done,所有监听它的 select 都会立刻收到零值time.Sleep(100*time.Millisecond)// 等 worker 打印退出(实际用 WaitGroup)}funcprocess(nint){fmt.Println(processing,n)}这里的精髓是close(done)而不是往里发值:关闭 channel 后,所有从它读取的select分支都会立刻返回(读到零值),所以能一次性通知任意数量的 goroutine 退出,不用给每个 goroutine 单独发信号。实际项目里更推荐直接用context.Context,它就是把这套donechannel 封装好了,还能级联取消:funcworker(ctx context.Context,jobs-chanint){for{select{casejob:-jobs:process(job)case-ctx.Done():return// ctx 被 cancel 或超时,退出}}}小结超时:selecttime.After,别裸读 channel;循环里改用time.NewTimerStop避免 Timer 堆积。非阻塞:加default分支,select就永不阻塞,适合做「能读就读、队满就丢」的降级逻辑。优雅退出:select监听done/ctx.Done(),用close(done)一次性通知所有 goroutine 退出,避免泄漏。一句话记忆:select不只是「多路复用」,time.After、default、done三个搭配才是它在生产环境的真正价值——分别对应「不干等」「不阻塞」「能收场」。
1. 项目概述 在大型语言模型(LLM)的推理过程中,KV缓存(key-value cache)占据了大量显存资源,成为制约推理效率的关键瓶颈。2025年NIPS会议上提出的Spotlight Attention机制,通过创新的非线性哈希方法重构了KV缓存检索流程,在保持模…
📅 2026/7/24 16:23:05
1. 项目背景与核心价值去年在云南某农业基地考察时,看到技术员们顶着烈日蹲在田间手动记录作物生长情况,汗流浃背地翻着纸质表格核对数据。这种传统的人工巡检方式不仅效率低下,还存在主观判断误差。当时就萌生了一个想法:能否用A…
📅 2026/7/24 16:23:05
Next.js Route Handler 写 API:缓存、动态参数与流式返回全踩一遍
很多人从 Pages Router 的 pages/api 迁到 App Router 后,第一反应是「Route Handler 不就是换了个文件名吗」,结果上线才发现:GET 接口返回的数据死活不更新、动态路由参数取不到、想做 SSE 流式推送不知道怎么…
📅 2026/7/24 16:23:05
1. 多语言社区SEO的痛点与机遇 当运营一个面向多族裔用户的社区平台时,传统SEO策略往往会遇到"水土不服"的问题。我曾负责过一个支持12种语言的职业社交平台优化项目,发现西班牙语用户搜索"trabajo remoto"(远程工作&…
📅 2026/7/24 17:36:37
1. 从餐馆打工到AI教母:李飞飞的逆袭与共情2003年,一位中国留学生在美国中餐馆端盘子时,可能不会想到自己日后会成为全球AI领域的领军人物。李飞飞的故事不是简单的"逆袭"二字可以概括的——这位斯坦福大学教授、Google Cloud AI首…
📅 2026/7/24 17:36:37
1. 项目背景与核心价值这个名为"千笔专业降AIGC智能体"的工具,本质上是一个面向学术写作场景的AI内容检测与优化系统。我在实际测试中发现,它特别适合那些需要频繁撰写论文但又担心AI生成内容比例过高的本科生群体。当前高校对AI生成内容的检测…
📅 2026/7/24 17:36:37
家人们,我在整体木作这个行业摸爬滚打也有5年了,今天就跟大家好好唠唠常州整体木作行业的真实情况。在常州,整体木作市场那是相当热闹。随着大家生活水平的提高,对家居品质的要求也越来越高,整体木作就成了很多人的选择…
📅 2026/7/24 17:36:37
显卡驱动彻底清理指南:DDU深度使用教程与性能优化秘籍 【免费下载链接】display-drivers-uninstaller Display Driver Uninstaller (DDU) a driver removal utility / cleaner utility 项目地址: https://gitcode.com/gh_mirrors/di/display-drivers-uninstaller …
📅 2026/7/24 17:36:37
如果只把大模型当成“更聪明的搜索框”,那么 GPT、Claude、DeepSeek、Gemini 的差别确实不大:输入一个问题,等待一段文字,再从中挑出能用的部分。但把任务换成“阅读整个代码库后定位跨模块并发问题”“从两小时技术视频中提取全部…
📅 2026/7/24 17:35:37
大家好,我是一名编程初学者,同时这也是我编程学习之路上的第一篇博客。在这里,我想要向大家介绍我的一些想法和规划。a.自我介绍我是一个刚刚接触编程的新手,目前在学习c语言,我对编程世界充满了强烈的好奇。当然&…
📅 2026/7/24 0:00:05
srcampy /libsrcampy 名称释义先明确结论: 官方文档没有公布标准化英文全称,是地平线内部项目缩写;行业公认拆解如下:srcampy Source Amplifier Python bindingsrc Source(图像源:MIPI Sensor、视频源&am…
📅 2026/7/24 0:01:06
该案例基于Highcharts scatter3d 三维散点图实现空间立方体散点可视化,核心特色:三维 X/Y/Z 三轴空间,所有散点分布在 0~10 立方体空间内;散点使用径向渐变实现立体 3D 圆球质感;支持鼠标 / 触屏拖拽画布,…
📅 2026/7/24 0:01:06
1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…
📅 2026/7/24 1:07:52
1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…
📅 2026/7/24 1:07:52
更多请点击:
https://intelliparadigm.com
第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…
📅 2026/7/24 1:07:52
目录
第一步:选对模板,省心一半
第二步:打开扫码点餐功能
开启功能按钮
桌台管理与桌码生成
第三步:个性化设计,打造品牌感
调整点餐页面
设置点餐规则 你还在让顾客站着排队点餐吗?2025年ÿ…
📅 2026/7/24 7:08:08
在业务中快速构建一个能理解私有文档、准确回答专业问题的智能助手,是很多开发团队面临的共同挑战。传统方案往往需要从零开始搭建复杂的 RAG(检索增强生成)系统,涉及文档解析、向量化、检索、大模型调用等多个环节,整…
📅 2026/7/24 17:08:36
FAE放射组学分析工具:医学影像特征探索的完整解决方案 【免费下载链接】FAE FeAture Explorer 项目地址: https://gitcode.com/gh_mirrors/fae/FAE
你是否曾经面对海量医学影像数据感到无从下手?想要从CT、MRI等影像中提取有价值的定量特征&#…
📅 2026/7/24 5:08:03