如何在单个线程中实现多间隔CPU使用率统计(systemd服务)
单线程实现多周期CPU统计任务方案
核心思路是在现有每秒执行的线程循环内,通过计数器累计或时间戳对比的逻辑,判断当前是否到达100秒、1000秒的触发节点,无需新增线程。
具体实现方式
1. 计数器累计法
适合线程执行周期稳定(严格每秒一次)的场景:
- 在线程内部初始化一个整数计数器(如
cycle_count),初始值为0。 - 每次线程执行时,先将计数器加1。
- 优先执行每秒必做任务:计算当前1秒CPU使用率,写入
cpu_usage_last_second.txt。 - 判断
cycle_count % 100 == 0,满足则执行100秒周期任务:计算最近100秒CPU使用率,写入cpu_usage_last_100_seconds.txt。 - 判断
cycle_count % 1000 == 0,满足则执行1000秒周期任务:计算最近1000秒CPU使用率,写入cpu_usage_last_1000_seconds.txt。 - 可选:当计数器达到1000时重置为0,避免整数溢出。
2. 时间戳对比法
适合线程可能因系统负载出现微小延迟的场景,精度更可靠:
- 在线程内部记录三个时间戳:
last_100s_time、last_1000s_time,初始值为当前系统秒级时间(可通过time()函数获取)。 - 每次线程执行时,先获取当前时间戳
current_time。 - 执行每秒任务:计算并写入
cpu_usage_last_second.txt。 - 计算
current_time - last_100s_time >= 100,满足则执行100秒周期任务,同时更新last_100s_time为current_time。 - 同理,计算
current_time - last_1000s_time >= 1000,满足则执行1000秒周期任务,更新对应时间戳。
代码示例(C语言)
#include <time.h> #include <stdio.h> #include <unistd.h> // 假设已有计算指定周期CPU使用率的函数 double calculate_cpu_usage(int interval_sec); void cpu_monitor_thread() { time_t last_100s = time(NULL); time_t last_1000s = time(NULL); int cycle_count = 0; while (1) { cycle_count++; time_t now = time(NULL); // 每秒执行:写入1秒CPU使用率 double usage_1s = calculate_cpu_usage(1); FILE* fp = fopen("cpu_usage_last_second.txt", "a"); if (fp) { fprintf(fp, "%.2f\n", usage_1s); fclose(fp); } // 每100秒执行:写入100秒CPU使用率 if (cycle_count % 100 == 0 || (now - last_100s) >= 100) { double usage_100s = calculate_cpu_usage(100); fp = fopen("cpu_usage_last_100_seconds.txt", "a"); if (fp) { fprintf(fp, "%.2f\n", usage_100s); fclose(fp); } last_100s = now; cycle_count = 0; // 重置计数器避免溢出 } // 每1000秒执行:写入1000秒CPU使用率 if ((now - last_1000s) >= 1000) { double usage_1000s = calculate_cpu_usage(1000); fp = fopen("cpu_usage_last_1000_seconds.txt", "a"); if (fp) { fprintf(fp, "%.2f\n", usage_1000s); fclose(fp); } last_1000s = now; } // 休眠1秒,保证基础执行周期 sleep(1); } }
注意事项
- 计算多周期CPU使用率时,需保留对应周期的历史
/proc/stat快照,比如计算100秒使用率,需存储100秒前的统计数据,触发时用当前快照减去历史快照计算差值。 - 文件写入需处理异常(如权限不足、磁盘满),避免线程因IO错误崩溃。
- 若线程休眠存在延迟,时间戳对比法会自动补偿偏差,比计数器法更准确。
内容的提问来源于stack exchange,提问作者Xershy
相关产品推荐
相关产品推荐

