如何在OS X上以Objective C / C获得总CPU空闲时间?

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

如果可能请提供代码示例。 这是我用来获取这些指标的代码。 结果百分比与Activity Monitor中的百分比不同。 所以我假设CPU时间计算不正确:

#include  #include  #include  #include  #include  - (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使用率,而不是绝对值。

这对应于在模式中调用时选项-cn to top:

  top -cn -l 0 | head -5 

这是默认模式。 如果您想要在代码中返回的值,那么您需要使用以下方法将值基于立即样本:

  top -ce -l 0 | head -5 

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

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

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

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

我们改变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; } 

然后我们采取两个样本(样本之间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; 

添加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); } 

因此,当您调用printSample(&deltasample)它会打印增量记录,该记录的值与topActivity 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]; }