如何在OS X上的Objective C/C中获得总的CPU空闲时间? [英] How to get total CPU Idle Time in Objective C/C on OS X?

查看:101
本文介绍了如何在OS X上的Objective C/C中获得总的CPU空闲时间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在OS X上的Objective C/C中获得总的CPU空闲时间吗?

I need to get total CPU Idle Time in Objective C/C on OS X?

如果可能,请提供执行此操作的代码示例. 这是我用来获取这些指标的代码.结果,百分比与我在活动监视器"中所占的百分比不同.因此,我认为CPU时间计算不正确:

If possible please provide code example which do that. Here is a code I use to get these metrics. As result percentage is not the same I have in Activity Monitor. So I assume CPU time calculation is incorrect:

#include <sys/sysctl.h>
#include <sys/types.h>
#include <mach/mach.h>
#include <mach/processor_info.h>
#include <mach/mach_host.h>

- (void)printCPUUsage
{
    processor_cpu_load_info_t cpuLoad;
    mach_msg_type_number_t processorMsgCount;
    natural_t processorCount;

    uint64_t totalSystemTime = 0, totalUserTime = 0, totalIdleTime = 0, totalCPUTime = 0;

    kern_return_t err = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &processorCount, (processor_info_array_t *)&cpuLoad, &processorMsgCount);

    for (natural_t i = 0; i < processorCount; i++) {

        // Calc load types and totals, with guards against 32-bit overflow
        // (values are natural_t)
        uint64_t system = 0, user = 0, idle = 0, total = 0;

        system = cpuLoad[i].cpu_ticks[CPU_STATE_SYSTEM];
        user = cpuLoad[i].cpu_ticks[CPU_STATE_USER];
        idle = cpuLoad[i].cpu_ticks[CPU_STATE_IDLE];

        total = system + user + idle;

        if (total < 1) {
            total = 1;
        }

        totalCPUTime += total;
        totalSystemTime += system;
        totalUserTime += user;
        totalIdleTime += idle;
    }


    double onePercent = totalCPUTime/100.0f;

    NSLog(@"system: %f", (double)totalSystemTime/(double)onePercent);
    NSLog(@"user: %f", (double)totalUserTime/(double)onePercent);
    NSLog(@"idle: %f", (double)totalIdleTime/(double)onePercent);
}

推荐答案

默认情况下,从过程仪表或顶部返回的值是基于样本增量的,即它们从上一个样本开始计算CPU使用率,而不是绝对值.值.

The values as returned from the process meter or top are, by default, sample delta based i.e. they calculate the CPU usage since the previous sample, rather than the absolute values.

在模式下调用时,这对应于顶部的选项-c n:

This corresponds to the option -c n to top when called in the mode:

 top -c n -l 0 | head -5

这是默认模式.如果您希望代码返回值,那么您需要使用以下方法将这些值基于即时样本:

Which is the default mode. If you want the values as returned in your code, then you need to base the values on immediate samples, using:

 top -c e -l 0 | head -5

这些值将与您看到的值相对应.

These values will correspond to the values you're seeing.

如果要获得与过程仪表/顶部相似的值,则需要获取两个样本,并显示它们之间的差异值.

If you want to get similar values to the process meter/top, then you need to take two samples, and display the values of the differences between them.

例如,我们创建一个包含统计信息的结构:

So for example, we create a structure containing the stats:

struct cpusample {
    uint64_t totalSystemTime;
    uint64_t totalUserTime;
    uint64_t totalIdleTime;

};

我们更改printCPUUsage调用,使其执行示例:

we alter the printCPUUsage call so that it performs a sample:

void sample(struct cpusample *sample)
{
    processor_cpu_load_info_t cpuLoad;
    mach_msg_type_number_t processorMsgCount;
    natural_t processorCount;

    uint64_t totalSystemTime = 0, totalUserTime = 0, totalIdleTime = 0;

    kern_return_t err = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &processorCount, (processor_info_array_t *)&cpuLoad, &processorMsgCount);

    for (natural_t i = 0; i < processorCount; i++) {

        // Calc load types and totals, with guards against 32-bit overflow
        // (values are natural_t)
        uint64_t system = 0, user = 0, idle = 0;

        system = cpuLoad[i].cpu_ticks[CPU_STATE_SYSTEM];
        user = cpuLoad[i].cpu_ticks[CPU_STATE_USER] + cpuLoad[i].cpu_ticks[CPU_STATE_NICE];
        idle = cpuLoad[i].cpu_ticks[CPU_STATE_IDLE];

        totalSystemTime += system;
        totalUserTime += user;
        totalIdleTime += idle;
    }
    sample->totalSystemTime = totalSystemTime;
    sample->totalUserTime = totalUserTime;
    sample->totalIdleTime = totalIdleTime;
}

然后我们进行两个采样(采样之间1秒):

Then we take two samples (1 second between samples):

struct cpusample delta;
sample(&sample1);
sleep(1);
sample(&sample2);
deltasample.totalSystemTime = sample2.totalSystemTime - sample1.totalSystemTime;
deltasample.totalUserTime = sample2.totalUserTime - sample1.totalUserTime;
deltasample.totalIdleTime = sample2.totalIdleTime - sample1.totalIdleTime;

添加打印样本代码:

void printSample(struct cpusample *sample)
{
    uint64_t total = sample->totalSystemTime + sample->totalUserTime + sample->totalIdleTime;

    double onePercent = total/100.0f;

    NSLog(@"system: %f", (double)sample->totalSystemTime/(double)onePercent);
    NSLog(@"user: %f", (double)sample->totalUserTime/(double)onePercent);
    NSLog(@"idle: %f", (double)sample->totalIdleTime/(double)onePercent);
}

因此,当您调用printSample(&deltasample)时,它会打印增量记录,该记录的值与topActivity Monitor给出的值更加相似.

so when you invoke printSample(&deltasample) it prints the delta record, which gives a much more similar value to the one presented by either top or Activity Monitor.

但是,老实说,我会使用host_statistics,因为代码更简洁:

But to be honest, I'd use host_statistics, as the code is cleaner:

void sample(struct cpusample *sample)
{
    kern_return_t kr;
    mach_msg_type_number_t count;
    host_cpu_load_info_data_t r_load;

    uint64_t totalSystemTime = 0, totalUserTime = 0, totalIdleTime = 0;

    count = HOST_CPU_LOAD_INFO_COUNT;
    kr = host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (int *)&r_load, &count);
    if (kr != KERN_SUCCESS) {
        printf("oops: %s\n", mach_error_string(kr));
        return;
    }

    sample->totalSystemTime = r_load.cpu_ticks[CPU_STATE_SYSTEM];
    sample->totalUserTime = r_load.cpu_ticks[CPU_STATE_USER] + r_load.cpu_ticks[CPU_STATE_NICE];
    sample->totalIdleTime = r_load.cpu_ticks[CPU_STATE_IDLE];
}

这篇关于如何在OS X上的Objective C/C中获得总的CPU空闲时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆