Ser*_*gio 7 c macos objective-c cpu-usage
我需要在OS X上获得目标C/C的总CPU空闲时间吗?
如果可能的话请提供代码示例.这是我用来获取这些指标的代码.结果百分比与我在Activity Monitor中的百分比不同.所以我假设CPU时间计算不正确:
#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);
}
Run Code Online (Sandbox Code Playgroud)
    默认情况下,从过程仪表或顶部返回的值基于样本增量,即它们计算自上一个样本以来的CPU使用量,而不是绝对值.
这对应-c n于在模式中调用时top 的选项:
 top -c n -l 0 | head -5
Run Code Online (Sandbox Code Playgroud)
这是默认模式.如果您想要在代码中返回的值,那么您需要使用以下示例将值基于立即样本:
 top -c e -l 0 | head -5
Run Code Online (Sandbox Code Playgroud)
这些值将与您看到的值相对应.
如果要获得与过程仪表/顶部相似的值,则需要采用两个样本,并显示它们之间差异的值.
例如,我们创建一个包含统计信息的结构:
struct cpusample {
    uint64_t totalSystemTime;
    uint64_t totalUserTime;
    uint64_t totalIdleTime;
};
Run Code Online (Sandbox Code Playgroud)
我们改变printCPUUsage调用,以便它执行一个示例:
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;
}
Run Code Online (Sandbox Code Playgroud)
然后我们采取两个样本(样本之间1秒):
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;
Run Code Online (Sandbox Code Playgroud)
添加printample代码:
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);
}
Run Code Online (Sandbox Code Playgroud)
因此,当您调用printSample(&deltasample)它时,它会打印增量记录,这会给出与其中任何一个top或多个记录相似的值Activity Monitor.
但说实话,我会使用host_statistics,因为代码更清晰:
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];
}
Run Code Online (Sandbox Code Playgroud)
        |   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           3314 次  |  
        
|   最近记录:  |