首页 > 其他分享 >Golang代码导致cpu高的原因你知道吗????

Golang代码导致cpu高的原因你知道吗????

时间:2024-09-18 14:49:55浏览次数:8  
标签:case default 代码 阻塞 CPU Golang 轮询 cpu

这段代码中出现高 CPU 使用率的原因主要是由于忙轮询(busy-waiting)问题。让我们仔细分析下这个问题:

代码分析
go
复制代码
select {
case v := <-ch:
// 从通道接收到值 v
default:
// 无数据可接收,走到 default 分支
}
case v := <-ch: 尝试从通道 ch 中接收数据。如果通道中有数据,这个分支会被执行,v 会被赋值。
default: 如果通道中没有数据,执行 default 分支。
为什么会导致高 CPU 使用率?
在这个结构中,当通道 ch 中没有数据时,程序会立即跳到 default 分支。这意味着程序不会阻塞,而是会继续执行后续的逻辑。如果这段代码位于一个循环中,程序将会非常频繁地尝试从通道中读取数据,但由于没有数据,它会不断地快速进入 default 分支。因为每次检查都非常快(没有任何阻塞),CPU 将被大量占用,这就是忙轮询。

典型的高 CPU 使用情境
假设代码像这样被用在一个循环中:

go
复制代码
for {
select {
case v := <-ch:
fmt.Println(v)
default:
// 执行其他操作或什么都不做
}
}
在这种情况下,程序将以极高的频率尝试从通道 ch 中接收数据。当通道没有数据时,它会不断地进入 default 分支并重复执行,导致 CPU 空转(一直在处理无效操作)。这种频繁的检查没有任何阻塞操作,导致 CPU 的使用率迅速上升。

解决方案
使用阻塞机制:在没有数据可用时可以让 Goroutine 休息,减少 CPU 占用率。例如,可以在 default 分支中加入短暂的 sleep 来避免忙轮询。
go
复制代码
for {
select {
case v := <-ch:
fmt.Println(v)
default:
time.Sleep(10 * time.Millisecond) // 适当的休眠降低CPU占用
}
}
避免频繁的非阻塞操作:如果不需要紧急响应,可以避免使用非阻塞的 select。在通道上没有数据时,允许 Goroutine 阻塞等待是更为有效的做法。比如直接使用阻塞式接收:
go
复制代码
for v := range ch {
fmt.Println(v)
}
这段代码会在通道 ch 中有数据时接收数据,而在没有数据时阻塞,直到有新的数据进入通道。

定期轮询(带时间间隔):如果一定要使用 default 分支,可以通过 time.After 来设置定期轮询,而不是频繁尝试接收数据:
go
复制代码
for {
select {
case v := <-ch:
fmt.Println(v)
case <-time.After(10 * time.Millisecond): // 定期执行
fmt.Println("No data, waiting...")
}
}
总结
高 CPU 使用率的主要原因是因为代码进入了忙轮询状态,即没有数据时没有任何阻塞或延迟操作,导致 CPU 不断地循环尝试获取数据。通过引入适当的阻塞、休眠或时间间隔可以有效降低 CPU 占用,避免程序因过度轮询而导致性能问题。

标签:case,default,代码,阻塞,CPU,Golang,轮询,cpu
From: https://www.cnblogs.com/fangdongbai/p/18418468

相关文章

  • 【2024研赛】【华为杯】2024 年研究生数学建模比赛思路、代码更新中.....
    【2024研赛】【华为杯】2024年研究生数学建模比赛思路、代码更新中...........
  • 图形学系列教程,带你从零开始入门图形学(包含配套代码)—— 透明度和深度
    图形学系列专栏序章初探图形编程第1章你的第一个三角形第2章变换顶点变换视图矩阵&帧速率第3章纹理映射第4章透明度和深度第5章裁剪区域和模板缓冲区第6章场景图第7章场景管理第8章索引缓冲区第9章骨骼动画第10章后处理第11章实时光照(一)第12章实时光照(二)......
  • 毕业论文实证分析的一套基础流程代码:描述性 相关性 检验 回归 分析、稳健性分析
    第一步:描述性分析sscinstallasdocasdocsumyx1x2x3x4x5x6x7 第二步:数据处理取对数foreachvarofvarlistyx1x2x3x4x5x6x7{genln`var'=log(`var')}如果有缩尾winsor2 lnylnx1lnx2lnx3lnx4lnx5lnx6lnx7,replacecuts(199) 第三步:......
  • Docker安装MySQL8.0.39报错:Fatal glibc error: CPU does not support x86-64-v2
    用Docker升级MySQL时报错Fatalglibcerror:CPUdoesnotsupportx86-64-v2,在网上找了很久资料,发现是MySQL的新镜像使用的是OracleLinux9,当前服务器的CPU无法安装这个所以报错,解决方法就是更换镜像版本这是我的解决方案,基于Dockerfile生成镜像:FROMm.daocloud.io/docker.......
  • 【编程底层原理】Java执行CAS后底层由谁执行cmpxchg指令?CPU?是否会导致从用户态切换
    Java中的CAS操作是由Java虚拟机(JVM)提供的原子类实现的,这些原子类利用了底层硬件的CAS指令,比如x86架构中的cmpxchg指令。以下是这个过程的一些关键点:原子类封装:Java的java.util.concurrent.atomic包提供了一系列的原子类,如AtomicInteger、AtomicLong等,它们封装了CAS操作,使得......
  • 【Java】若依(ruoyi)——7.代码生成(二)细节操作
    之前我们已经学习了代码生成的基础使用:https://www.cnblogs.com/luyj00436/p/18398248。即创建数据库并根据三种数据结构生成代码。1.基本信息和生成信息 前缀可以在配置表设置默认配置。单应用在resources目录下的application.yml,多模块ruoyi-generator中的resources目录下......
  • 使用sourceinsight阅读内核代码的一些问题
    工具栏格式乱了怎么办https://blog.csdn.net/qq_23327993/article/details/115567723Linux内核中有很多宏定义,sourceinsight不识别,导致解析出问题https://blog.csdn.net/nust20/article/details/46486947https://www.jianshu.com/p/0b4ad9532367https://tjtech.me/how-to-fix......
  • OpenHarmony WIFI代码关键目录
    OpenHarmonyWIFI代码关键目录一wpa_supplicant代码F:\CodeSpace\Openharmony_20231026\third_party\wpa_supplicant\wpa_supplicant-2.9_standard  二WIFIFramework层代码F:\CodeSpace\Openharmony_20231026\foundation\communication\wifi 三openssl代码  ......
  • GBase 8a 使用cpulimit限制进程序cpu占用
    cpulimit是一个限制进程的CPU使用率的工具(以百分比表示,而不是CPU时间)。其工作原理是为进程预设一个CPU占用率限制,并实时监控进程是否超出此限,若超出则让该进程暂停运行一段时间。它不会更改nice值或其他调度优先级设置,而是更改真实的CPU使用率。此外,它能够动态地、快速地适应整个......
  • 简洁优秀的代码记录
    1、简洁的队列初始化:查询对象中某个属性,存在直接返回值,不存在,初始化该属性;一般写法:varobj={};vargetQueue=(key)=>{if(!obj[key]){obj[key]=[]}returnobj[key]}精简写法:exportdefaultfunctionmitt(all:EventHandlerMap){all=......