可以将主函数中的 while
循环内容抽象成一个单独的函数,以提高代码的可读性和可维护性。以下是重构后的代码示例,其中 monitor_cpu_and_send_heartbeat
函数包含了原先 while
循环的逻辑:
#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");
}
void monitor_cpu_and_send_heartbeat(int tfd) {
uint64_t expirations;
int heartbeat_counter = 0;
while (1) {
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(tfd, &readfds);
// 等待事件发生
select(tfd + 1, &readfds, NULL,NULL,NULL);
if (FD_ISSET(tfd ,&readfds)) {
read(tfd,&expirations,sizeof(expirations));
// 每次触发都记录 CPU 占用率,并检查是否需要发送心跳
record_cpu_usage();
heartbeat_counter++;
if (heartbeat_counter >= 30) { // 每30秒发送一次心跳
heartbeat();
heartbeat_counter = 0; // 重置计数器
}
}
}
}
int main() {
// 创建定时器文件描述符
int tfd = timerfd_create(CLOCK_MONOTONIC, 0);
if (tfd == -1) {
perror("timerfd_create");
exit(EXIT_FAILURE);
}
struct itimerspec new_value;
new_value.it_value.tv_sec = 1;
new_value.it_value.tv_nsec = 0;
new_value.it_interval.tv_sec = 1;
new_value.it_interval.tv_nsec = 0;
timerfd_settime(tfd, 0, &new_value, NULL);
monitor_cpu_and_send_heartbeat(tfd); // 调用监测和心跳函数
close(tfd);
return EXIT_SUCCESS;
}
在这个版本中,monitor_cpu_and_send_heartbeat
函数负责监控 CPU 使用情况并发送心跳。主函数现在更简洁,只需设置定时器并调用该新函数即可。这种结构化使得代码更易于理解和维护。
内容由零声教学AI助手提供,问题来源于学员提问