找回密码
 立即注册
首页 业界区 安全 cpu 使用率是怎么回事呢?

cpu 使用率是怎么回事呢?

寨重 2025-8-5 05:23:50
前言

简单介绍一下cpu的使用率是怎么来的。
正文

cpu 使用大概有这几方面:
  1. public class CpuTimeBreakdown
  2. {
  3.     // 1. 用户时间 (User Time)
  4.     // - 应用程序在用户态执行的时间
  5.     // - 包括:业务逻辑、算法计算、数据处理
  6.     public long UserTime { get; set; }
  7.    
  8.     // 2. 系统时间 (System Time)
  9.     // - 应用程序在内核态执行的时间
  10.     // - 包括:系统调用、内存管理、进程调度
  11.     public long SystemTime { get; set; }
  12.    
  13.     // 3. 空闲时间 (Idle Time)
  14.     // - CPU真正空闲的时间
  15.     // - 包括:HALT指令、节能模式、等待中断
  16.     public long IdleTime { get; set; }
  17.    
  18.     // 4. I/O等待时间 (I/O Wait Time)
  19.     // - CPU等待I/O设备的时间
  20.     // - 包括:磁盘I/O、网络I/O、设备I/O
  21.     public long IoWaitTime { get; set; }
  22.    
  23.     // 5. 中断时间 (IRQ Time)
  24.     // - 处理硬件中断的时间
  25.     // - 包括:网络中断、磁盘中断、定时器中断
  26.     public long IrqTime { get; set; }
  27.    
  28.     // 6. 软中断时间 (Soft IRQ Time)
  29.     // - 处理软中断的时间
  30.     // - 包括:网络包处理、定时器处理、调度器中断
  31.     public long SoftIrqTime { get; set; }
  32.    
  33.     // 7. 虚拟化时间 (Steal Time)
  34.     // - 被虚拟机监控器占用的时间
  35.     public long StealTime { get; set; }
  36. }
复制代码
然后计算公式如下:
  1. public class CpuUsageCalculator
  2. {
  3.     public static CpuUsageBreakdown CalculateCpuUsage(CpuTimeSnapshot current, CpuTimeSnapshot previous)
  4.     {
  5.         var totalDiff = current.TotalTime - previous.TotalTime;
  6.         
  7.         return new CpuUsageBreakdown
  8.         {
  9.             // 总CPU使用率 = (总时间 - 空闲时间 - I/O等待时间) / 总时间
  10.             TotalUsage = (double)(totalDiff - current.IdleTime + previous.IdleTime -
  11.                                  current.IoWaitTime + previous.IoWaitTime) / totalDiff * 100,
  12.             
  13.             // 用户态使用率
  14.             UserUsage = (double)(current.UserTime - previous.UserTime) / totalDiff * 100,
  15.             
  16.             // 系统态使用率
  17.             SystemUsage = (double)(current.SystemTime - previous.SystemTime) / totalDiff * 100,
  18.             
  19.             // 中断使用率
  20.             IrqUsage = (double)(current.IrqTime + current.SoftIrqTime -
  21.                                previous.IrqTime - previous.SoftIrqTime) / totalDiff * 100,
  22.             
  23.             // I/O等待率
  24.             IoWaitUsage = (double)(current.IoWaitTime - previous.IoWaitTime) / totalDiff * 100,
  25.             
  26.             // 空闲率
  27.             IdleUsage = (double)(current.IdleTime - previous.IdleTime) / totalDiff * 100
  28.         };
  29.     }
  30. }
复制代码
这里就有人问了,cpu 为啥会有空闲时间呢? cpu 应该是一直会运行的,那么这个空闲时间是什么呢?
  1. public class IdleTimeExplanation
  2. {
  3.     public static void ExplainIdleTime()
  4.     {
  5.         Console.WriteLine("CPU空闲时间包括:");
  6.         Console.WriteLine("1. HALT指令执行时间 - CPU进入低功耗状态");
  7.         Console.WriteLine("2. 等待中断的时间 - 没有可执行的任务");
  8.         Console.WriteLine("3. 节能模式时间 - CPU降频或休眠");
  9.         Console.WriteLine("4. 调度器空闲时间 - 没有就绪进程");
  10.         Console.WriteLine("5. 内核空闲循环 - 执行idle进程");
  11.     }
  12. }
复制代码
在操作系统重,会执行idle 进程,不让cpu空闲下来,这个是为了让cpu不脱离操作系统的控制。
  1. // Linux内核中的空闲进程
  2. public class IdleProcess
  3. {
  4.     public static void IdleLoop()
  5.     {
  6.         while (true)
  7.         {
  8.             // 1. 检查是否有就绪进程
  9.             if (HasReadyProcess())
  10.             {
  11.                 ScheduleNextProcess();
  12.                 break;
  13.             }
  14.             
  15.             // 2. 执行HALT指令,进入低功耗状态
  16.             HaltCpu();
  17.             
  18.             // 3. 等待中断唤醒
  19.             WaitForInterrupt();
  20.             
  21.             // 4. 处理中断
  22.             HandleInterrupt();
  23.         }
  24.     }
  25.    
  26.     private static void HaltCpu()
  27.     {
  28.         // 执行HLT指令,CPU进入低功耗状态
  29.         // 但CPU仍然可以响应中断
  30.     }
  31. }
复制代码
那么这里的软中断和硬中断是怎么占用cpu的时间的?
按照我们的思维上来说,处理软中断和硬中断呢? 理论上cpu只是会找到特定的程序的位置,但是处理算是系统处理,应该算在系统上吧。
那么我们看一下定义:系统时间是什么定义:
系统时间是应用程序在内核态执行的时间。
那么这里看到,其实内核调用呢?分为两个部分一个是系统时间,一个是中断时间。
  1. public class InterruptVsSystemTime
  2. {
  3.     public static void ExplainDifference()
  4.     {
  5.         Console.WriteLine("中断时间 vs 系统时间的区别:");
  6.         Console.WriteLine();
  7.         Console.WriteLine("系统时间 (System Time):");
  8.         Console.WriteLine("- 应用程序主动发起的系统调用");
  9.         Console.WriteLine("- 进程在用户态主动调用内核函数");
  10.         Console.WriteLine("- 例如:read(), write(), malloc()");
  11.         Console.WriteLine("- 进程知道何时开始和结束");
  12.         Console.WriteLine();
  13.         Console.WriteLine("中断时间 (IRQ Time):");
  14.         Console.WriteLine("- 硬件设备强制中断当前执行");
  15.         Console.WriteLine("- CPU被动响应中断信号");
  16.         Console.WriteLine("- 例如:网卡中断、磁盘中断");
  17.         Console.WriteLine("- 进程不知道何时发生中断");
  18.         Console.WriteLine("- 中断处理程序在内核态执行");
  19.     }
  20. }
复制代码
执行的上下文也不同 :
  1. public class ExecutionContext
  2. {
  3.     public static void DemonstrateContext()
  4.     {
  5.         Console.WriteLine("执行上下文对比:");
  6.         Console.WriteLine();
  7.         Console.WriteLine("系统调用上下文:");
  8.         Console.WriteLine("用户进程 -> 系统调用 -> 内核函数 -> 返回用户进程");
  9.         Console.WriteLine("主动发起,可预测,进程控制");
  10.         Console.WriteLine();
  11.         Console.WriteLine("中断处理上下文:");
  12.         Console.WriteLine("用户进程 -> 硬件中断 -> 中断处理程序 -> 返回用户进程");
  13.         Console.WriteLine("被动响应,不可预测,硬件控制");
  14.     }
  15. }
复制代码
那么同样有人会疑问了,硬中断是硬件中断的,软中断是软件中断的? 真的是这个概念吗? 如果是这样,系统调用不也是软中断嘛?
那么来看一下系统调用和软中断的区别:
1.1 基本概念对比
  1. public class SystemCallVsSoftInterrupt
  2. {
  3.     public static void ExplainDifference()
  4.     {
  5.         Console.WriteLine("系统调用 vs 软中断:");
  6.         Console.WriteLine();
  7.         Console.WriteLine("系统调用 (System Call):");
  8.         Console.WriteLine("- 用户程序主动发起的请求");
  9.         Console.WriteLine("- 通过特定的指令序列触发");
  10.         Console.WriteLine("- 进程知道何时发生");
  11.         Console.WriteLine("- 同步执行");
  12.         Console.WriteLine("- 例如:read(), write(), malloc()");
  13.         Console.WriteLine();
  14.         Console.WriteLine("软中断 (Soft IRQ):");
  15.         Console.WriteLine("- 内核或硬件触发的异步事件");
  16.         Console.WriteLine("- 通过设置标志位触发");
  17.         Console.WriteLine("- 进程不知道何时发生");
  18.         Console.WriteLine("- 异步执行");
  19.         Console.WriteLine("- 例如:网络包处理、定时器处理");
  20.     }
  21. }
复制代码
1.2 触发机制的不同
  1. ; 系统调用的触发机制
  2. system_call:
  3.     ; 1. 用户程序执行syscall指令
  4.     syscall
  5.    
  6.     ; 2. CPU自动切换到内核态
  7.     ; 3. 跳转到系统调用处理程序
  8.     ; 4. 执行系统调用逻辑
  9.     ; 5. 返回用户态
  10. ; 软中断的触发机制
  11. soft_irq:
  12.     ; 1. 内核或硬件设置软中断标志
  13.     set_bit(SOFTIRQ_BIT, &softirq_pending)
  14.    
  15.     ; 2. 在适当时机检查软中断标志
  16.     ; 3. 执行软中断处理程序
  17.     ; 4. 清除软中断标志
复制代码
软中断流程:
  1. public class SoftInterruptFlow
  2. {
  3.     public static void DemonstrateSoftInterrupt()
  4.     {
  5.         Console.WriteLine("软中断执行流程:");
  6.         Console.WriteLine();
  7.         Console.WriteLine("触发阶段:");
  8.         Console.WriteLine("1. 硬件中断处理程序设置软中断标志");
  9.         Console.WriteLine("2. 硬件中断处理完成");
  10.         Console.WriteLine("3. 返回被中断的进程");
  11.         Console.WriteLine();
  12.         Console.WriteLine("执行阶段:");
  13.         Console.WriteLine("4. 内核在适当时机检查软中断标志");
  14.         Console.WriteLine("5. 发现有待处理的软中断");
  15.         Console.WriteLine("6. 执行软中断处理程序");
  16.         Console.WriteLine("7. 清除软中断标志");
  17.         Console.WriteLine();
  18.         Console.WriteLine("特点:异步、不可预测、内核控制");
  19.     }
  20. }
复制代码
软中断的实现:
  1. // Linux内核软中断实现
  2. void do_softirq(void)
  3. {
  4.     unsigned long pending;
  5.    
  6.     // 获取待处理的软中断
  7.     pending = local_softirq_pending();
  8.    
  9.     if (pending) {
  10.         // 执行软中断处理程序
  11.         if (pending & (1 << NET_RX_SOFTIRQ))
  12.             net_rx_action();
  13.         
  14.         if (pending & (1 << TIMER_SOFTIRQ))
  15.             run_timer_softirq();
  16.         
  17.         if (pending & (1 << TASKLET_SOFTIRQ))
  18.             tasklet_action();
  19.     }
  20. }
复制代码
大概就是这样一个过程:
  1. public class HardInterrupt
  2. {
  3.     public static void ExplainHardInterrupt()
  4.     {
  5.         Console.WriteLine("硬中断 (Hard IRQ):");
  6.         Console.WriteLine();
  7.         Console.WriteLine("定义:");
  8.         Console.WriteLine("- 由硬件设备直接发送到CPU的中断信号");
  9.         Console.WriteLine("- CPU必须立即响应的紧急事件");
  10.         Console.WriteLine("- 具有最高优先级");
  11.         Console.WriteLine("- 可以打断任何正在执行的代码");
  12.         Console.WriteLine();
  13.         Console.WriteLine("特点:");
  14.         Console.WriteLine("- 硬件触发");
  15.         Console.WriteLine("- 立即响应");
  16.         Console.WriteLine("- 不可屏蔽(某些情况下)");
  17.         Console.WriteLine("- 执行时间短");
  18.     }
  19. }
复制代码


这里介绍了cpu的使用率是怎么回事,里面介绍了应用时间、系统时间、中断时间、空闲时间的概念,和他们之间的去呗,更有利于排查cpu高的问题,或者cpu不高,但是系统很慢,了解这些概念后,就容易根据这几个方面去排查。

来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除

相关推荐

您需要登录后才可以回帖 登录 | 立即注册