Swift中如何正确获取CPU负载百分比?
CPU负载百分比获取异常问题修复
问题现象
尝试获取当前CPU负载百分比时,运行代码后数据异常:
- 打印
stats.cpu_ticks得到的数值几乎无变化:
| 时间 | cpu_tick[0] | cpu_tick[1] | cpu_tick[2] | cpu_tick[3] |
|---|---|---|---|---|
| 1秒 | 1810101 | 782080 | 22191087 | 0 |
| 2秒 | 1810214 | 782122 | 22191725 | 0 |
| 3秒 | 1810322 | 782158 | 22192376 | 0 |
- 输出的CPU负载百分比完全固定不变:
| 时间 | system | user | idle | nice |
|---|---|---|---|---|
| 1秒 | 3% | 7% | 89% | 0% |
| 2秒 | 3% | 7% | 89% | 0% |
| 3秒 | 3% | 7% | 89% | 0% |
问题根源
查看getCPUUsage()的实现:
public func getCPUUsage() { var test = LoadInfo() let cpuUsage = test.cpuUsage() print("\tSYSTEM: \(Int(cpuUsage.system))%") print("\tUSER: \(Int(cpuUsage.user))%") print("\tIDLE: \(Int(cpuUsage.idle))%") print("\tNICE: \(Int(cpuUsage.nice))%") }
每次调用getCPUUsage()都会创建全新的LoadInfo实例,导致用于存储上一次CPU tick数据的loadPrevious变量每次都回到初始状态。第一次调用时计算的是当前tick与初始值的差值,之后每次新建实例,loadPrevious重置,计算出的差值和百分比自然不会变化。
修复方案
将LoadInfo实例改为getCPUUsage()所在类的成员变量,让它持续保存loadPrevious的状态,而非每次调用都重新创建:
步骤1:修改类的成员变量
在包含getCPUUsage()的类中,添加持久化的LoadInfo成员变量:
class YourClass { private var loadInfoInstance = LoadInfo() // 作为成员变量持久化 public func getCPUUsage() { let cpuUsage = loadInfoInstance.cpuUsage() print("\tSYSTEM: \(Int(cpuUsage.system))%") print("\tUSER: \(Int(cpuUsage.user))%") print("\tIDLE: \(Int(cpuUsage.idle))%") print("\tNICE: \(Int(cpuUsage.nice))%") } // 原updateStatistics方法保持不变 private func updateStatistics() { getCPUUsage() } }
步骤2:初始化LoadInfo的基准数据
确保LoadInfo结构体初始化时就获取一次CPU数据作为初始基准:
struct LoadInfo { private var loadPrevious: host_cpu_load_info init() { // 初始化时获取首次CPU数据作为基准 loadPrevious = LoadInfo.hostCPULoadInfo() } // 原hostCPULoadInfo和cpuUsage方法保持不变 }
原理说明
修改后,loadInfoInstance会在类的生命周期中持续存在,每次调用cpuUsage()时,loadPrevious会保存上一次的CPU tick数据,计算差值时用的是当前tick与上一秒tick的差,这样就能得到正确的CPU负载百分比变化。
内容的提问来源于stack exchange,提问作者4c65736975
相关产品推荐
相关产品推荐

