iOS – 从应用程序获取CPU使用率
有谁知道如何获得应用程序的CPU使用率? 这绝对是可能的,因为有应用程序商店( 活动监视器触摸 ),它可以显示它的应用程序。
更新 。 此代码正在为我工作:
更新2 。 thread_list正在泄漏,所以添加了vm_deallocate
#import <mach/mach.h> #import <assert.h> float cpu_usage() { 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 < (int)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; }
对于Swift 3:
fileprivate func cpuUsage() -> Double { var kr: kern_return_t var task_info_count: mach_msg_type_number_t task_info_count = mach_msg_type_number_t(TASK_INFO_MAX) var tinfo = [integer_t](repeating: 0, count: Int(task_info_count)) kr = task_info(mach_task_self_, task_flavor_t(TASK_BASIC_INFO), &tinfo, &task_info_count) if kr != KERN_SUCCESS { return -1 } var thread_list: thread_act_array_t? = UnsafeMutablePointer(mutating: [thread_act_t]()) var thread_count: mach_msg_type_number_t = 0 defer { if let thread_list = thread_list { vm_deallocate(mach_task_self_, vm_address_t(UnsafePointer(thread_list).pointee), vm_size_t(thread_count)) } } kr = task_threads(mach_task_self_, &thread_list, &thread_count) if kr != KERN_SUCCESS { return -1 } var tot_cpu: Double = 0 if let thread_list = thread_list { for j in 0 ..< Int(thread_count) { var thread_info_count = mach_msg_type_number_t(THREAD_INFO_MAX) var thinfo = [integer_t](repeating: 0, count: Int(thread_info_count)) kr = thread_info(thread_list[j], thread_flavor_t(THREAD_BASIC_INFO), &thinfo, &thread_info_count) if kr != KERN_SUCCESS { return -1 } let threadBasicInfo = convertThreadInfoToThreadBasicInfo(thinfo) if threadBasicInfo.flags != TH_FLAGS_IDLE { tot_cpu += (Double(threadBasicInfo.cpu_usage) / Double(TH_USAGE_SCALE)) * 100.0 } } // for each thread } return tot_cpu } fileprivate func convertThreadInfoToThreadBasicInfo(_ threadInfo: [integer_t]) -> thread_basic_info { var result = thread_basic_info() result.user_time = time_value_t(seconds: threadInfo[0], microseconds: threadInfo[1]) result.system_time = time_value_t(seconds: threadInfo[2], microseconds: threadInfo[3]) result.cpu_usage = threadInfo[4] result.policy = threadInfo[5] result.run_state = threadInfo[6] result.flags = threadInfo[7] result.suspend_count = threadInfo[8] result.sleep_time = threadInfo[9] return result }
尝试这个:
- (NSString *)cpuUsage { 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 @"NA"; } 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 @"NA"; } if (thread_count > 0) stat_thread += thread_count; long tot_idle = 0; long tot_user = 0; long tot_kernel = 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 nil; } basic_info_th = (thread_basic_info_t)thinfo; if (basic_info_th->flags & TH_FLAGS_IDLE) { //This is idle tot_idle = tot_idle + basic_info_th->user_time.microseconds + basic_info_th->system_time.microseconds; } else { //This is user tot_user = tot_user + basic_info_th->user_time.microseconds; //This is kernel tot_kernel = tot_kernel + basic_info_th->system_time.microseconds; } } // for each thread kr = vm_deallocate(mach_task_self(), (vm_offset_t)thread_list, thread_count * sizeof(thread_t)); assert(kr == KERN_SUCCESS); long tot_cpu = tot_idle + tot_user + tot_kernel return [NSString stringWithFormat:@"Idle: %.2f, User: %.2f, Kernel: %.2f", tot_idle/tot_cpu, tot_user/tot_cpu, tot_kernel/tot_cpu]; }
但是,该方法会根据每个进程的起点计算百分比。 如果你正在寻找更传统的方法来计算这些数字,请参阅Petesh的答案 。