如何在运行时使用POSIX clock()函数监控CPU利用率?

psi*_*lia 4 c embedded time posix clock

有没有可靠的方法程序如何在运行时测量其CPU利用率?

我可能不得不使用time.h中的POSIX clock()函数.这个想法首先使用几毫秒来设置空闲CPU负载(步骤A),然后是全CPU负载(步骤B),然后启动程序并不断调用clock().因此,我可以计算相对于步骤A和步骤B计算的CPU利用率,以监控百分比中的CPU利用率.我假设所有其他后台进程都被忽略.

但是,我不确定,如何实现这些步骤A和步骤B,只使用C89和POSIX正确地说idle()和full_load()函数?

Jas*_*son 5

当你说"full_load",并且你只需要一个CPU或虚拟核心负载时,一个简单的紧密循环就可以解决问题.当然,它不会使用芯片上的所有晶体管(也就是说,我们不是在谈论"满载"的老化测试),但它会在预定的时间片内获得CPU ,使用所有可用的时钟周期,没有可以放弃对内核的控制的系统调用,并可能导致执行线程重新调度以供日后使用.您还可以使用带有信号处理程序的警报来退出循环.这样就可以让你在大约一秒的执行时间内运行循环(警报并不完全是时间准确的......它们是接近的,但不是时钟周期).

此外,对于"空闲"加载部分,您可以执行相同的操作,但使用sigsuspend()而不是紧密循环,等待警报响起.

所以你的代码看起来像下面这样:

#include <signal.h>
#include <unistd.h>
#include <time.h>
#include <stdio.h>

static sig_atomic_t alarm_flag = 1;

void alarm_handler(int arg)
{
    alarm_flag = 0;
}

clock_t idle()
{
    //setup the alarm flag
    alarm_flag = 1;

    //setup the signal masks
    sigset_t old_signal_set;
    sigset_t new_signal_set;

    sigemptyset(&old_signal_set);
    sigemptyset(&new_signal_set);

    //block the alarm signal
    sigaddset(&new_signal_set, SIGALRM);
    sigprocmask(SIG_BLOCK, &new_signal_set, &old_signal_set);

    //setup the alarm
    alarm(1);

    clock_t time_before = clock();

    //sit idle while we wait for the alarm to go off
    while(alarm_flag)
        sigsuspend(&old_signal_set);

    clock_t time_after = clock();

    //restore the old signal mask
    sigprocmask(SIG_SETMASK, &old_signal_set, NULL);

    return time_after - time_before;
}

clock_t full_load()
{
    //set the alarm signal
    alarm_flag = 1;

    //set the 1-second alarm
    alarm(1);

    clock_t time_before = clock();

    //loop until the alarm goes off
    while(alarm_flag);

    clock_t time_after = clock();

    return time_after - time_before;
}

int main()
{
    //setup the signal handler for the alarm
    sigset(SIGALRM, alarm_handler);

    //call the functions
    clock_t idle_time = idle();
    clock_t load_time = full_load();

    //... do whatever else you need to-do with this info
    printf("Idle Time: %d\n", (int)idle_time);
    printf("Load Time: %d\n", (int)load_time);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

请记住,根据POSIX标准,每秒应该有100万个时钟作为该clock_t值的时基,因此您应该看到为"full_load"返回的数字接近该数字,因为我们是"满负荷"大约一秒钟.闲置负载应该非常小(当然).这是我在Mac Pro上生成的数字:

Idle Time: 31
Load Time: 1000099
Run Code Online (Sandbox Code Playgroud)

因此,只要知道您可以看到多少个时钟周期,这似乎与您所寻找的内容有些一致clock().我当然会多次运行这个并取平均值来获得你可能看到的方差的更好指标.