一、说明
我们在开发中,有可能会需要读取应用所占CPU的百分比以及CPU的使用率。本篇文章主要是介绍这两个利用率的概念以及如何拿到这两个利用率。
cpu总量 = 本应用所占的空间 + 其它应用所占的空间 + 空闲的空间
应用所占百分比:本应用的程序所在cpu的占有率
cpu的使用率:目前手机cpu的使用率 = 本应用使用率+其它应用使用率
二、代码
1.获取应用所占cpu的百分比:
导入以下库:
#import <mach/mach.h>
具体代码:
/**
* Get cpu usage app level
*
* @return cpu usage
*/
+ (float)getCpuUsageAppLevel
{
kern_return_t kr;
task_info_data_t tinfo;
mach_msg_type_number_t task_info_count;
task_info_count = TASK_INFO_MAX;
kr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)tinfo, &task_info_count);
if (kr != KERN_SUCCESS) {
return -1;
}
task_basic_info_t basic_info;
thread_array_t thread_list;
mach_msg_type_number_t thread_count;
thread_info_data_t thinfo;
mach_msg_type_number_t thread_info_count;
thread_basic_info_t basic_info_th;
uint32_t stat_thread = 0; // Mach threads
basic_info = (task_basic_info_t)tinfo;
// get threads in the task
kr = task_threads(mach_task_self(), &thread_list, &thread_count);
if (kr != KERN_SUCCESS) {
return -1;
}
if (thread_count > 0)
stat_thread += thread_count;
long tot_sec = 0;
long tot_usec = 0;
float tot_cpu = 0;
int j;
for (j = 0; j < thread_count; j++)
{
thread_info_count = THREAD_INFO_MAX;
kr = thread_info(thread_list[j], THREAD_BASIC_INFO,
(thread_info_t)thinfo, &thread_info_count);
if (kr != KERN_SUCCESS) {
return -1;
}
basic_info_th = (thread_basic_info_t)thinfo;
if (!(basic_info_th->flags & TH_FLAGS_IDLE)) {
tot_sec = tot_sec + basic_info_th->user_time.seconds + basic_info_th->system_time.seconds;
tot_usec = tot_usec + basic_info_th->user_time.microseconds + basic_info_th->system_time.microseconds;
tot_cpu = tot_cpu + basic_info_th->cpu_usage / (float)TH_USAGE_SCALE * 100.0;
}
} // for each thread
kr = vm_deallocate(mach_task_self(), (vm_offset_t)thread_list, thread_count * sizeof(thread_t));
assert(kr == KERN_SUCCESS);
return tot_cpu;
}
我们可以和xcode上的cpu利用百分比进行比对,其值比较接近。
2.获取手机cpu的使用率
1)在主线程中计算
导入以下库:
#import <mach/mach.h>
#import <sys/sysctl.h>
#import <sys/types.h>
#import "AppCalculator.h"
需要声明的属性:
processor_info_array_t _cpuInfo, _prevCPUInfo;
mach_msg_type_number_t _numCPUInfo, _numPrevCPUInfo;
unsigned _numCPUs;
/**
* Get cpu usage phone level
*
* @return cpu usage
*/
- (float)getCpuUsagePhoneLevel
{
float cpuusageRes = 0.00f;
int _mib[2U] = { CTL_HW, HW_NCPU };
size_t _sizeOfNumCPUs = sizeof(_numCPUs);
int _status = sysctl(_mib, 2U, &_numCPUs, &_sizeOfNumCPUs, NULL, 0U);
if(_status)
_numCPUs = 1;
// _cpuUsageLock = [[NSLock alloc] init];
natural_t _numCPUsU = 0U;
kern_return_t err = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &_numCPUsU, &_cpuInfo, &_numCPUInfo);
if(err == KERN_SUCCESS) {
// [_cpuUsageLock lock];
for(unsigned i = 0U; i < _numCPUs; ++i) {
Float32 _inUse, _total;
if(_prevCPUInfo) {
_inUse = (
(_cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_USER] - _prevCPUInfo[(CPU_STATE_MAX * i) + CPU_STATE_USER])
+ (_cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_SYSTEM] - _prevCPUInfo[(CPU_STATE_MAX * i) + CPU_STATE_SYSTEM])
+ (_cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_NICE] - _prevCPUInfo[(CPU_STATE_MAX * i) + CPU_STATE_NICE])
);
_total = _inUse + (_cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_IDLE] - _prevCPUInfo[(CPU_STATE_MAX * i) + CPU_STATE_IDLE]);
} else {
_inUse = _cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_USER] + _cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_SYSTEM] + _cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_NICE];
_total = _inUse + _cpuInfo[(CPU_STATE_MAX * i) + CPU_STATE_IDLE];
}
if (_total != 0) {
cpuusageRes += _inUse / _total;
}
// NSLog(@"Core : %u, Usage: %.2f%%", i, _inUse / _total * 100.f);
}
// [_cpuUsageLock unlock];
if(_prevCPUInfo) {
size_t prevCpuInfoSize = sizeof(integer_t) * _numPrevCPUInfo;
vm_deallocate(mach_task_self(), (vm_address_t)_prevCPUInfo, prevCpuInfoSize);
}
_prevCPUInfo = _cpuInfo;
_numPrevCPUInfo = _numCPUInfo;
_cpuInfo = nil;
_numCPUInfo = 0U;
} else {
// NSLog(@"Error!");
}
return cpuusageRes * 100;
}
2)把计算cpu利用率的代码放到非主线程中去计算
代码连接http://download.csdn.net/download/smiling8866/9475124
注意,代码中需要先调用- (void)createCpuUsagePhoneLevel方法去计算cpu利用率,然后再调用- (float)getCpuUsagePhoneLevel方法拿到值。
注意:注意代码异常等细节。