ZBLOG

使用timerfd 如何再回调函数同时记录1s前后cpu占用率的变化以及30s周期心跳呢

要实现一个使用 timerfd 的程序,在回调函数中记录 CPU 占用率的变化以及每 30 秒的心跳,可以按照以下步骤进行:

  1. 创建两个定时器:一个用于记录 CPU 占用率变化(例如每秒触发一次),另一个用于发送心跳信号(每 30 秒触发一次)。
  2. 读取 CPU 占用率:可以通过 /proc/stat 文件获取 CPU 使用情况。
  3. 在回调函数中处理事件:当定时器到期时,调用相应的函数来计算和打印 CPU 占用率,同时处理心跳。

下面是一个示例代码,演示如何实现上述逻辑:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/timerfd.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>  
#include <errno.h>

void record_cpu_usage() {
    static long prev_idle = 0;
    static long prev_total = 0;

    FILE *fp = fopen("/proc/stat", "r");
    if (!fp) {
        perror("fopen");
        return;
    }

    char buffer[256];
    fgets(buffer, sizeof(buffer), fp);
    
    // 从 /proc/stat 中读取CPU信息
    long user, nice, system, idle, iowait, irq, softirq;
    sscanf(buffer, "cpu %ld %ld %ld %ld %ld %ld %ld", &user, &nice, &system, &idle, &iowait, &irq, &softirq);

    // 计算总时间和空闲时间
    long total = user + nice + system + idle + iowait + irq + softirq;
    
    // 计算CPU占用率
    long diff_idle = idle - prev_idle;
    long diff_total = total - prev_total;

    if (diff_total > 0) {
        double cpu_usage = (double)(diff_total - diff_idle) / diff_total * 100.0;
        printf("CPU Usage: %.2f%%\n", cpu_usage);
    }

    // 更新前一个值
    prev_idle = idle;
    prev_total = total;

    fclose(fp);
}

void heartbeat() {
   printf("Heartbeat: System is alive!\n");
}

int main() {
   // 创建定时器文件描述符
   int tfd_cpu = timerfd_create(CLOCK_MONOTONIC, 0);
   int tfd_heartbeat = timerfd_create(CLOCK_MONOTONIC, 0);

   if (tfd_cpu == -1 || tfd_heartbeat == -1) {
       perror("timerfd_create");
       exit(EXIT_FAILURE);
   }

   struct itimerspec new_value_cpu;
   new_value_cpu.it_value.tv_sec = 1; 
   new_value_cpu.it_value.tv_nsec = 0; 
   new_value_cpu.it_interval.tv_sec = 1; 
   new_value_cpu.it_interval.tv_nsec = 0; 

   struct itimerspec new_value_heartbeat;
   new_value_heartbeat.it_value.tv_sec = 30; 
   new_value_heartbeat.it_value.tv_nsec = 0; 
   new_value_heartbeat.it_interval.tv_sec = 30; 
   new_value_heartbeat.it_interval.tv_nsec = 0; 

   timerfd_settime(tfd_cpu, 0, &new_value_cpu, NULL);
   timerfd_settime(tfd_heartbeat, 0, &new_value_heartbeat, NULL);

   uint64_t expirations;

   while (1) {
       fd_set readfds;
       FD_ZERO(&readfds);
       FD_SET(tfd_cpu, &readfds);
       FD_SET(tfd_heartbeat, &readfds);

       // 等待事件发生
       int max_fd = (tfd_cpu > tfd_heartbeat) ? tfd_cpu : tfd_heartbeat;
       select(max_fd + 1, &readfds, NULL, NULL,NULL);

       if (FD_ISSET(tfd_cpu, &readfds)) {
           read(tfd_cpu,&expirations,sizeof(expirations));
           record_cpu_usage();
       }

       if (FD_ISSET(tfd_heartbeat ,&readfds)) {
           read(tfd_heartbeat,&expirations,sizeof(expirations));
           heartbeat();
       }
   }

   close(tfd_cpu);
   close(tfd_heartbeat);
   
return EXIT_SUCCESS;
}

程序说明

  1. 创建两个定时器:分别用于 CPU 使用率记录(每秒)和心跳消息(每30秒)。
  2. 获取 CPU 占用率
    • 使用 /proc/stat 文件中的数据。解析文件内容以提取用户态、系统态、空闲态等信息。
    • 每次计算出新的一秒内的总时间与上一次的对比,得出 CPU 的占用比例。
  3. 循环监听事件
    • 使用 select() 来检测哪一个定时器到了超时时间。
    • 在相应的条件满足时,通过 read() 来清除超时时间,并调用相应的处理函数。

注意事项

  • 确保在 Linux 环境下运行此程序,因为它依赖于 /proc/stat 文件来获取 CPU 信息。
  • 根据需求可能需要增加错误处理逻辑或其他功能,例如多线程支持或信号处理等。

这个例子展示了如何结合 timerfd 和 CPU 占用率监测,以达到您所需的效果。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:http://sdn.0voice.com/?id=6939

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?