美文网首页内存
获取CPU的使用率

获取CPU的使用率

作者: 谌文 | 来源:发表于2020-01-27 23:46 被阅读0次
    怎样才能地址苹果手机CPU使用率呢?

    CPU 是移动设备最重要的组成部分,如果开发者写的代码有问题导致CPU负载过高,会导致app使用过程中发生卡顿,同时也可能导致手机发热发烫,耗电过快,严重影响用户体验。
    如果想避免CPU负载过高可以通过检测app的CPU使用率,然后可以发现导致CPU过高的代码,并根据具体情况优化。那该如何检测CPU使用率呢?大学期间学过计算机的应该都上过操作系统这门课,学过的都知道线程CPU是调度和分配的基本单位,而应用作为进程运行时,包含了多个不同的线程,这样如果我们能知道app里所有线程占用 CPU 的情况,也就能知道整个app的 CPU 占用率。幸运的是我们在Mach 层中 thread_basic_info 结构体发现了我们想要的东西,thread_basic_info 结构体定义如下:

    struct thread_basic_info {
            time_value_t    user_time;      /* user run time */
            time_value_t    system_time;    /* system run time */
            integer_t       cpu_usage;      /* scaled cpu usage percentage */
            policy_t        policy;         /* scheduling policy in effect */
            integer_t       run_state;      /* run state (see below) */
            integer_t       flags;          /* various flags (see below) */
            integer_t       suspend_count;  /* suspend count for thread */
            integer_t       sleep_time;     /* number of seconds that thread
                                               has been sleeping */
    };
    
    

    其中cpu_usage即为该线程的CPU使用率,接下来我们需要获取app的所有线程,iOS内核提供了 thread_info API 调用获取指定 task 的线程列表,然后可以通过 thread_info API 调用来查询指定线程的信息,thread_info API 在 thread_act.h 中定义。

    kern_return_t task_threads
    (
        task_t target_task,
        thread_act_array_t *act_list,
        mach_msg_type_number_t *act_listCnt
    );
    

    task_threads 将 target_task 任务中的所有线程保存在 act_list 数组中。
    现在我们能够取得app的所有线程,并且能够取得每个线程的CPU使用率,这样获取app的CPU使用率的代码就呼之欲出,直接上代码:

    - (CGFloat)usedCpu {
        kern_return_t kr = { 0 };
        task_info_data_t tinfo = { 0 };
        mach_msg_type_number_t 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 0.0f;
        }
        
        task_basic_info_t basic_info = { 0 };
        thread_array_t thread_list = { 0 };
        mach_msg_type_number_t thread_count = { 0 };
        
        thread_info_data_t thinfo = { 0 };
        thread_basic_info_t basic_info_th = { 0 };
        
        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 0.0f;
        }
        
        long tot_sec = 0;
        long tot_usec = 0;
        float tot_cpu = 0;
        
        for (int i = 0; i < thread_count; i++) {
            mach_msg_type_number_t thread_info_count = THREAD_INFO_MAX;
            
            kr = thread_info(thread_list[i], THREAD_BASIC_INFO, (thread_info_t)thinfo, &thread_info_count);
            if (kr != KERN_SUCCESS) {
                return 0.0f;
            }
            
            basic_info_th = (thread_basic_info_t)thinfo;
            if ((basic_info_th->flags & TH_FLAGS_IDLE) == 0) {
                tot_sec = tot_sec + basic_info_th->user_time.seconds + basic_info_th->system_time.seconds;
                tot_usec = tot_usec + basic_info_th->system_time.microseconds + basic_info_th->system_time.microseconds;
                tot_cpu = tot_cpu + basic_info_th->cpu_usage / (float)TH_USAGE_SCALE;
            }
        }
        
        kr = vm_deallocate( mach_task_self(), (vm_offset_t)thread_list, thread_count * sizeof(thread_t) );
        if (kr != KERN_SUCCESS) {
            return 0.0f;
        }
        
        return (CGFloat)tot_cpu * 100;
    }
    

    有了获取CPU使用率的方法后我们只要再加个定时器去实时查询,并将得到的结果显示在界面上即可:

     - (void)startMonitoringWithNoticeBlock:(void(^)(CGFloat value))noticeBlock {
        self.noticeBlock = noticeBlock;
    
        _timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(noticeCPUValue) userInfo:nil repeats:YES];
    }
    
    - (void)noticeCPUValue {
        if (self.noticeBlock) {
            self.noticeBlock([self usedCpu]);
        }
    }
    
    

    相关文章

      网友评论

        本文标题:获取CPU的使用率

        本文链接:https://www.haomeiwen.com/subject/ugiythtx.html