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

Go 如何避免频繁抢占?

前言

“能抢占”和“频繁抢占”是两回事。

如果抢占太频繁,会导致:

  • 上下文切换开销大
  • cache 失效
  • 调度成本增加
  • 性能下降

所以 Go 的设计目标是:

能抢占,但不会乱抢占。

我们一步步讲清楚它是怎么控制频率的。


一、核心原则:不是随时抢占,而是“时间片 + 条件触发”

Go 不会在每一行代码都尝试抢占。

它有两个重要控制点:

  1. 时间片机制(约 10ms)
  2. 安全点检查

二、时间片机制:限制抢占频率

每个 goroutine 不是无限制运行的。

调度器会:

给每个 G 一个大约 10ms 的运行时间片

只有当:

G 连续运行超过这个时间片

才会考虑抢占。

如果 goroutine 很快执行完或者主动阻塞(比如 channel),根本不会触发抢占。

所以:

✅ 短任务不会被频繁打断
✅ I/O 密集型任务也不会频繁打断
❌ 只有“长时间纯 CPU 任务”才会被抢占


三、不是立刻强制抢占,而是“设置抢占标志”

Go 不会马上暴力中断。

它会先:

g.preempt = true

也就是说:

这是一个“软请求”,不是立即打断。

真正中断发生在“安全点”。


四、安全点机制:避免高频打断

抢占只会发生在:

  • 函数调用边界
  • 栈检查点
  • 显式 safe point

而不会:

  • 在任意一条指令中断
  • 在 runtime 关键区中断

这样可以避免:

  • 每条指令都检查
  • 每个循环都中断
  • 极端高频切换

五、只有“长时间占用 P”才会被抢

Go 调度的核心目标不是公平到每个微秒。

它只关心:

有没有 G 长时间霸占 P?

如果没有,调度器甚至不会干预。

这是一种“懒调度策略”。


六、异步抢占也不是无脑触发

在 1.14+ 的异步抢占中:

Go 会通过信号打断线程。

但它不会:

  • 对所有 M 同时发信号
  • 对每个 G 都发信号
  • 在频繁循环里反复发信号

而是:

  • 只对运行过久的 G 发信号
  • 发一次信号后等待效果
  • 不会连续疯狂发送

七、syscall 不参与抢占

当 goroutine 进入:

syscall

它会:

  • 解绑 P
  • 让其他 G 运行

这属于“自然让出”,不是抢占。

所以很多程序即使有大量 IO,也不会频繁抢占。


八、调度器不会频繁扫描全局

调度器不会:

  • 每纳秒检查一次
  • 每个循环都检测

它是在:

  • 调度点
  • 定时检查点
  • 进入 runtime 时

才做判断。


九、避免频繁抢占的核心策略总结

可以记住这五点:

1️⃣ 有时间片阈值(≈10ms)
2️⃣ 只标记抢占,不立即中断
3️⃣ 只在安全点真正切换
4️⃣ 只抢占长时间运行的 G
5️⃣ 不重复发送信号

十、为什么这样设计?

如果每 1ms 抢占一次:

  • cache 会失效
  • 指令流水线会清空
  • 性能会暴跌

Go 的设计哲学是:

“足够公平,而不是绝对公平。”


十一、一个形象类比

想象 CPU 是一个会议室。

Go 的规则不是:

“每 1 分钟强制换人。”

而是:

“如果一个人讲超过 10 分钟还不下来,就提醒他。”

如果讲 2 分钟就结束?

根本不会打断。


十二、真正会频繁抢占的场景

只有在这种情况下才可能频繁抢占:

for {heavyCalculation()
}

纯 CPU 密集 + 无阻塞 + 单 P + 长时间运行

但即使如此:

  • 每 10ms 才会发生一次
  • 不会无限高频

十三、底层一句话总结

Go 通过:

时间片阈值 + 抢占标志 + 安全点 + 信号节流机制

避免了频繁抢占。

http://www.jsqmd.com/news/355971/

相关文章:

  • 2026上海陵园标杆推荐:传统中式墓、双朝南墓、草坪葬、花坛葬、树葬、壁葬、16万墓,瀛新园以多元生态葬式,守护生命与自然共生 - 海棠依旧大
  • 2026年上海公墓行业优质机构参考:至尊园传统中式墓、至尊园双朝南墓、至尊园草坪葬、至尊园花坛葬、至尊园树葬、至尊园壁葬、至尊园16万墓、传承人文的生命纪念场所 - 海棠依旧大
  • 2026上海墓地服务推荐:草坪葬墓地、花坛葬墓地、树葬墓地、壁葬墓地、16万墓地优选指南,望仙安息园公墓以多元墓式筑就逝者安心之所 - 海棠依旧大
  • 第十五课:缓存三大灾难——穿透、击穿、雪崩的系统解法
  • 第五章 part01
  • 2026上海公墓推荐:汇龙园墓园、传统中式墓、双朝南墓、左右放墓、艺术墓、草坪葬、花坛葬、树葬、壁葬、16万墓、生态葬,殡葬服务优选 - 海棠依旧大
  • 从 SAS 到 MAS:构建高效、可扩展的 AI Agent 架构演进
  • 探索大数据领域 Hadoop 的分布式存储奥秘
  • FPGA信息交互的奇妙之旅:PCle与光纤协同工作探秘
  • BISHI19 乒乓球
  • 2026年上海福寿园公墓参考:福寿园墓地、福寿园墓园、福寿园传统中式墓、福寿园双朝南墓、福寿园草坪葬、福寿园花坛葬、福寿园树葬、福寿园壁葬、福寿园16万墓、人文纪念与生态安葬的践行者 - 海棠依旧大
  • 获取类的内容
  • 2026年上海公墓优质机构参考:上海清竹园、清竹园传统中式墓、清竹园双朝南墓、清竹园草坪葬、清竹园花坛葬、清竹园树葬、清竹园壁葬、清竹园16万墓、兼具人文底蕴与生态质感 - 海棠依旧大
  • 解析大数据领域存算分离的市场需求
  • 【小程序毕设全套源码+文档】基于Android的高校社团管理小程序的设计与实现(丰富项目+远程调试+讲解+定制)
  • 通过docker搭建windows的KMS激活工具
  • 【小程序毕设源码分享】基于springboot+Android的成人教育APP的设计与实现(程序+文档+代码讲解+一条龙定制)
  • 细胞多尺度仿真软件:MCell_(4).MCell的用户界面与基本操作
  • 【小程序毕设源码分享】基于springboot+Android宠物饲养管理APP的设计与实现(程序+文档+代码讲解+一条龙定制)
  • 细胞多尺度仿真软件:CellSys_(10).模型验证与优化
  • 从巴菲特投资看A股投资机会
  • 【小程序毕设源码分享】基于springboot+小程序的电影信息推荐APP的设计与实现(程序+文档+代码讲解+一条龙定制)
  • 浏览器编译后有2个图标-----没用
  • 【小程序毕设源码分享】基于springboot+Android的大学生勤工助学管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)
  • Flutter 混合开发:WebView 与原生完美融合实战
  • 【小程序毕设全套源码+文档】基于Android的电影信息推荐APP的设计与实现(丰富项目+远程调试+讲解+定制)
  • 大数据Storm:为企业实时数据处理保驾护航
  • AI语音识别在智能家居应用中的落地实践
  • 【小程序毕设全套源码+文档】基于Android的汉服交易小程序的设计与实现(丰富项目+远程调试+讲解+定制)
  • 【小程序毕设全套源码+文档】基于Android宠物饲养管理APP的设计与实现(丰富项目+远程调试+讲解+定制)