times 函数详解 Link to heading

1. 函数介绍 Link to heading

times 是POSIX标准函数,用于获取进程及其子进程的CPU时间统计信息。它返回自系统启动以来进程在用户态和内核态消耗的CPU时间,以及所有已终止子进程的CPU时间统计。这对于性能分析、资源监控和系统管理非常有用。

2. 函数原型 Link to heading

#include <sys/times.h>
clock_t times(struct tms *buf);

3. 功能 Link to heading

times 函数获取当前进程的CPU时间使用情况,包括用户态CPU时间、系统态CPU时间,以及所有已终止子进程的相应时间。这些信息对于进程性能分析和资源管理至关重要。

4. 参数 Link to heading

  • *struct tms buf: 指向tms结构体的指针,用于存储时间统计信息

5. 返回值 Link to heading

  • 成功: 返回自系统启动以来的滴答数(ticks)
  • 失败: 返回(clock_t)-1,并设置errno

6. 相似函数,或关联函数 Link to heading

  • clock: 获取进程CPU时间
  • getrusage: 获取资源使用情况
  • time/clock_gettime: 获取系统时间
  • wait/waitpid: 等待子进程并获取其资源使用情况

7. 示例代码 Link to heading

示例1:基础times使用 Link to heading

#include <sys/times.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>

/**
 * 显示CPU时间统计
 */
void show_cpu_times(const struct tms *tms_buf, clock_t ticks) {
    long clk_tck = sysconf(_SC_CLK_TCK);  // 获取每秒滴答数
    
    printf("CPU时间统计:\n");
    printf("  用户态时间: %jd 滴答 (%.3f 秒)\n", 
           (intmax_t)tms_buf->tms_utime, 
           (double)tms_buf->tms_utime / clk_tck);
    printf("  系统态时间: %jd 滴答 (%.3f 秒)\n", 
           (intmax_t)tms_buf->tms_stime, 
           (double)tms_buf->tms_stime / clk_tck);
    printf("  子进程用户态时间: %jd 滴答 (%.3f 秒)\n", 
           (intmax_t)tms_buf->tms_cutime, 
           (double)tms_buf->tms_cutime / clk_tck);
    printf("  子进程系统态时间: %jd 滴答 (%.3f 秒)\n", 
           (intmax_t)tms_buf->tms_cstime, 
           (double)tms_buf->tms_cstime / clk_tck);
    printf("  总滴答数: %jd\n", (intmax_t)ticks);
    printf("  系统滴答率: %ld 滴答/秒\n", clk_tck);
}

/**
 * 演示基础times使用方法
 */
int demo_times_basic() {
    struct tms tms_start, tms_end;
    clock_t start_ticks, end_ticks;
    long clk_tck;
    
    printf("=== 基础times使用示例 ===\n");
    
    // 获取系统滴答率
    clk_tck = sysconf(_SC_CLK_TCK);
    if (clk_tck == -1) {
        perror("获取系统滴答率失败");
        return -1;
    }
    
    printf("系统滴答率: %ld 滴答/秒\n", clk_tck);
    
    // 获取初始时间统计
    start_ticks = times(&tms_start);
    if (start_ticks == (clock_t)-1) {
        perror("获取初始时间统计失败");
        return -1;
    }
    
    printf("\n1. 初始时间统计:\n");
    show_cpu_times(&tms_start, start_ticks);
    
    // 执行一些CPU密集型操作
    printf("\n2. 执行CPU密集型操作...\n");
    
    volatile long sum = 0;
    for (long i = 0; i < 100000000; i++) {
        sum += i * i;
        if (i % 20000000 == 0) {
            printf("  进度: %ld%%\n", i / 1000000);
        }
    }
    
    printf("  计算结果: %ld\n", sum);
    
    // 获取结束时间统计
    end_ticks = times(&tms_end);
    if (end_ticks == (clock_t)-1) {
        perror("获取结束时间统计失败");
        return -1;
    }
    
    printf("\n3. 结束时间统计:\n");
    show_cpu_times(&tms_end, end_ticks);
    
    // 计算时间差
    printf("\n4. 时间差统计:\n");
    clock_t ticks_diff = end_ticks - start_ticks;
    clock_t utime_diff = tms_end.tms_utime - tms_start.tms_utime;
    clock_t stime_diff = tms_end.tms_stime - tms_start.tms_stime;
    
    printf("  消耗滴答数: %jd\n", (intmax_t)ticks_diff);
    printf("  用户态时间差: %jd 滴答 (%.3f 秒)\n", 
           (intmax_t)utime_diff, (double)utime_diff / clk_tck);
    printf("  系统态时间差: %jd 滴答 (%.3f 秒)\n", 
           (intmax_t)stime_diff, (double)stime_diff / clk_tck);
    printf("  总CPU时间: %.3f 秒\n", 
           (double)(utime_diff + stime_diff) / clk_tck);
    
    // 计算CPU使用率
    if (ticks_diff > 0) {
        double cpu_utilization = (double)(utime_diff + stime_diff) / ticks_diff * 100;
        printf("  CPU使用率: %.2f%%\n", cpu_utilization);
    }
    
    return 0;
}

int main() {
    return demo_times_basic();
}

示例2:父子进程CPU时间统计 Link to heading

#include <sys/times.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
#include <time.h>

/**
 * 子进程工作函数
 */
void child_work(int child_id, int work_duration) {
    printf("子进程 %d (PID: %d) 启动\n", child_id, getpid());
    
    struct tms tms_start, tms_current;
    clock_t start_ticks, current_ticks;
    long clk_tck = sysconf(_SC_CLK_TCK);
    
    start_ticks = times(&tms_start);
    
    // 执行工作
    volatile long sum = 0;
    time_t start_time = time(NULL);
    
    while (difftime(time(NULL), start_time) < work_duration) {
        // CPU密集型工作
        for (int i = 0; i < 1000000; i++) {
            sum += i;
        }
        
        // 定期报告进度
        if (difftime(time(NULL), start_time) > 0 && 
            fmod(difftime(time(NULL), start_time), 1.0) < 0.1) {
            current_ticks = times(&tms_current);
            if (current_ticks != (clock_t)-1) {
                clock_t utime_diff = tms_current.tms_utime - tms_start.tms_utime;
                printf("  子进程 %d: 用户态时间 %.3f 秒\n", 
                       child_id, (double)utime_diff / clk_tck);
            }
        }
    }
    
    printf("子进程 %d 完成,计算结果: %ld\n", child_id, sum);
    exit(child_id);
}

/**
 * 演示父子进程CPU时间统计
 */
int demo_parent_child_times() {
    struct tms tms_before, tms_after;
    clock_t ticks_before, ticks_after;
    pid_t children[3];
    int child_count = 3;
    long clk_tck = sysconf(_SC_CLK_TCK);
    
    printf("=== 父子进程CPU时间统计演示 ===\n");
    printf("系统滴答率: %ld 滴答/秒\n", clk_tck);
    
    // 获取父进程初始时间统计
    ticks_before = times(&tms_before);
    if (ticks_before == (clock_t)-1) {
        perror("获取初始时间统计失败");
        return -1;
    }
    
    printf("\n1. 父进程初始时间统计:\n");
    printf("  父进程用户态时间: %.3f 秒\n", 
           (double)tms_before.tms_utime / clk_tck);
    printf("  父进程系统态时间: %.3f 秒\n", 
           (double)tms_before.tms_stime / clk_tck);
    printf("  子进程累计时间: %.3f 秒 (用户态) + %.3f 秒 (系统态)\n",
           (double)tms_before.tms_cutime / clk_tck,
           (double)tms_before.tms_cstime / clk_tck);
    
    // 创建子进程
    printf("\n2. 创建子进程:\n");
    for (int i = 0; i < child_count; i++) {
        children[i] = fork();
        if (children[i] == 0) {
            // 子进程
            child_work(i + 1, 3 + i);  // 不同持续时间
        } else if (children[i] > 0) {
            printf("  创建子进程 %d: PID=%d\n", i + 1, children[i]);
        } else {
            perror("创建子进程失败");
            // 清理已创建的子进程
            for (int j = 0; j < i; j++) {
                kill(children[j], SIGKILL);
            }
            return -1;
        }
    }
    
    // 父进程等待子进程完成
    printf("\n3. 父进程等待子进程完成:\n");
    int completed_children = 0;
    
    while (completed_children < child_count) {
        int status;
        pid_t finished_pid = wait(&status);
        if (finished_pid > 0) {
            completed_children++;
            printf("  子进程 %d (PID=%d) 已完成,退出状态: %d\n", 
                   WEXITSTATUS(status), finished_pid, WEXITSTATUS(status));
        } else if (finished_pid == -1) {
            if (errno != EINTR) {
                perror("等待子进程失败");
                break;
            }
        }
    }
    
    // 获取父进程结束时间统计
    ticks_after = times(&tms_after);
    if (ticks_after == (clock_t)-1) {
        perror("获取结束时间统计失败");
        return -1;
    }
    
    printf("\n4. 父进程结束时间统计:\n");
    printf("  父进程用户态时间: %.3f 秒\n", 
           (double)tms_after.tms_utime / clk_tck);
    printf("  父进程系统态时间: %.3f 秒\n", 
           (double)tms_after.tms_stime / clk_tck);
    printf("  子进程累计时间: %.3f 秒 (用户态) + %.3f 秒 (系统态)\n",
           (double)tms_after.tms_cutime / clk_tck,
           (double)tms_after.tms_cstime / clk_tck);
    
    // 计算差异
    printf("\n5. 父子进程时间差异分析:\n");
    clock_t parent_utime_diff = tms_after.tms_utime - tms_before.tms_utime;
    clock_t parent_stime_diff = tms_after.tms_stime - tms_before.tms_stime;
    clock_t children_utime_diff = tms_after.tms_cutime - tms_before.tms_cutime;
    clock_t children_stime_diff = tms_after.tms_cstime - tms_before.tms_cstime;
    
    printf("  父进程CPU时间: %.3f 秒 (用户态) + %.3f 秒 (系统态) = %.3f 秒\n",
           (double)parent_utime_diff / clk_tck,
           (double)parent_stime_diff / clk_tck,
           (double)(parent_utime_diff + parent_stime_diff) / clk_tck);
    
    printf("  子进程CPU时间: %.3f 秒 (用户态) + %.3f 秒 (系统态) = %.3f 秒\n",
           (double)children_utime_diff / clk_tck,
           (double)children_stime_diff / clk_tck,
           (double)(children_utime_diff + children_stime_diff) / clk_tck);
    
    printf("  总CPU时间: %.3f 秒\n",
           (double)(parent_utime_diff + parent_stime_diff + 
                   children_utime_diff + children_stime_diff) / clk_tck);
    
    // 总体统计
    clock_t total_ticks = ticks_after - ticks_before;
    if (total_ticks > 0) {
        double total_cpu_time = (double)(parent_utime_diff + parent_stime_diff + 
                                       children_utime_diff + children_stime_diff) / clk_tck;
        double wall_clock_time = (double)total_ticks / clk_tck;
        double cpu_utilization = total_cpu_time / wall_clock_time * 100;
        
        printf("\n6. 总体性能统计:\n");
        printf("  墙钟时间: %.3f 秒\n", wall_clock_time);
        printf("  CPU时间: %.3f 秒\n", total_cpu_time);
        printf("  CPU利用率: %.2f%%\n", cpu_utilization);
        printf("  并行效率: %.2f%%\n", cpu_utilization / child_count);
    }
    
    return 0;
}

int main() {
    return demo_parent_child_times();
}

示例3:性能分析工具 Link to heading

#include <sys/times.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
#include <time.h>
#include <math.h>

/**
 * 性能分析结果结构
 */
typedef struct {
    clock_t start_ticks;
    clock_t end_ticks;
    struct tms start_tms;
    struct tms end_tms;
    double wall_time_seconds;
    double cpu_time_seconds;
    double user_time_seconds;
    double system_time_seconds;
    double children_user_time_seconds;
    double children_system_time_seconds;
    double cpu_utilization_percent;
} performance_analysis_t;

/**
 * 初始化性能分析
 */
int init_performance_analysis(performance_analysis_t *analysis) {
    analysis->start_ticks = times(&analysis->start_tms);
    if (analysis->start_ticks == (clock_t)-1) {
        perror("初始化性能分析失败");
        return -1;
    }
    
    return 0;
}

/**
 * 完成性能分析
 */
int finish_performance_analysis(performance_analysis_t *analysis) {
    long clk_tck = sysconf(_SC_CLK_TCK);
    
    analysis->end_ticks = times(&analysis->end_tms);
    if (analysis->end_ticks == (clock_t)-1) {
        perror("完成性能分析失败");
        return -1;
    }
    
    // 计算各种时间统计
    clock_t ticks_diff = analysis->end_ticks - analysis->start_ticks;
    clock_t utime_diff = analysis->end_tms.tms_utime - analysis->start_tms.tms_utime;
    clock_t stime_diff = analysis->end_tms.tms_stime - analysis->start_tms.tms_stime;
    clock_t cutime_diff = analysis->end_tms.tms_cutime - analysis->start_tms.tms_cutime;
    clock_t cstime_diff = analysis->end_tms.tms_cstime - analysis->start_tms.tms_cstime;
    
    analysis->wall_time_seconds = (double)ticks_diff / clk_tck;
    analysis->user_time_seconds = (double)utime_diff / clk_tck;
    analysis->system_time_seconds = (double)stime_diff / clk_tck;
    analysis->children_user_time_seconds = (double)cutime_diff / clk_tck;
    analysis->children_system_time_seconds = (double)cstime_diff / clk_tck;
    analysis->cpu_time_seconds = analysis->user_time_seconds + analysis->system_time_seconds +
                                 analysis->children_user_time_seconds + analysis->children_system_time_seconds;
    
    if (ticks_diff > 0) {
        analysis->cpu_utilization_percent = (analysis->cpu_time_seconds / 
                                           analysis->wall_time_seconds) * 100;
    } else {
        analysis->cpu_utilization_percent = 0.0;
    }
    
    return 0;
}

/**
 * 显示性能分析结果
 */
void show_performance_analysis(const performance_analysis_t *analysis) {
    printf("=== 性能分析报告 ===\n");
    printf("时间统计:\n");
    printf("  墙钟时间: %.3f 秒\n", analysis->wall_time_seconds);
    printf("  用户态时间: %.3f 秒\n", analysis->user_time_seconds);
    printf("  系统态时间: %.3f 秒\n", analysis->system_time_seconds);
    printf("  子进程用户态时间: %.3f 秒\n", analysis->children_user_time_seconds);
    printf("  子进程系统态时间: %.3f 秒\n", analysis->children_system_time_seconds);
    printf("  总CPU时间: %.3f 秒\n", analysis->cpu_time_seconds);
    printf("  CPU利用率: %.2f%%\n", analysis->cpu_utilization_percent);
    
    // 详细分解
    printf("\n详细分解:\n");
    if (analysis->wall_time_seconds > 0) {
        printf("  用户态占比: %.1f%%\n", 
               (analysis->user_time_seconds / analysis->wall_time_seconds) * 100);
        printf("  系统态占比: %.1f%%\n", 
               (analysis->system_time_seconds / analysis->wall_time_seconds) * 100);
        printf("  子进程用户态占比: %.1f%%\n", 
               (analysis->children_user_time_seconds / analysis->wall_time_seconds) * 100);
        printf("  子进程系统态占比: %.1f%%\n", 
               (analysis->children_system_time_seconds / analysis->wall_time_seconds) * 100);
    }
}

/**
 * CPU密集型测试函数
 */
void cpu_intensive_test(const char *test_name, int iterations) {
    printf("执行CPU密集型测试: %s (%d 次迭代)\n", test_name, iterations);
    
    volatile double result = 0.0;
    for (int i = 0; i < iterations; i++) {
        // 执行数学计算
        for (int j = 1; j <= 1000; j++) {
            result += sin(j * 0.001) * cos(j * 0.001);
        }
        
        // 定期显示进度
        if (i > 0 && i % (iterations / 10) == 0) {
            printf("  %s 进度: %d%%\n", test_name, (i * 100) / iterations);
        }
    }
    
    printf("  %s 完成,结果: %.6f\n", test_name, result);
}

/**
 * I/O密集型测试函数
 */
void io_intensive_test(const char *test_name, int file_count) {
    printf("执行I/O密集型测试: %s (%d 个文件)\n", test_name, file_count);
    
    for (int i = 0; i < file_count; i++) {
        char filename[64];
        snprintf(filename, sizeof(filename), "/tmp/io_test_%s_%d.tmp", test_name, i);
        
        // 创建并写入文件
        FILE *fp = fopen(filename, "w");
        if (fp) {
            for (int j = 0; j < 1000; j++) {
                fprintf(fp, "测试数据行 %d.%d\n", i, j);
            }
            fclose(fp);
        }
        
        // 读取文件
        fp = fopen(filename, "r");
        if (fp) {
            char buffer[256];
            while (fgets(buffer, sizeof(buffer), fp)) {
                // 简单处理读取的数据
                volatile int dummy = strlen(buffer);
            }
            fclose(fp);
        }
        
        // 删除临时文件
        unlink(filename);
        
        if (i > 0 && i % (file_count / 10) == 0) {
            printf("  %s 进度: %d%%\n", test_name, (i * 100) / file_count);
        }
    }
    
    printf("  %s 完成\n", test_name);
}

/**
 * 演示性能分析工具
 */
int demo_performance_analyzer() {
    performance_analysis_t analysis;
    long clk_tck = sysconf(_SC_CLK_TCK);
    
    printf("=== 性能分析工具演示 ===\n");
    printf("系统滴答率: %ld 滴答/秒\n", clk_tck);
    
    // 初始化性能分析
    if (init_performance_analysis(&analysis) != 0) {
        return -1;
    }
    
    printf("\n开始性能测试...\n");
    
    // 测试1: CPU密集型操作
    printf("\n1. CPU密集型测试:\n");
    cpu_intensive_test("CPU测试1", 5000);
    
    // 测试2: I/O密集型操作
    printf("\n2. I/O密集型测试:\n");
    io_intensive_test("I/O测试1", 50);
    
    // 测试3: 混合操作
    printf("\n3. 混合操作测试:\n");
    for (int i = 0; i < 5; i++) {
        cpu_intensive_test("混合CPU测试", 1000);
        io_intensive_test("混合I/O测试", 10);
    }
    
    // 完成性能分析
    if (finish_performance_analysis(&analysis) != 0) {
        return -1;
    }
    
    // 显示分析结果
    printf("\n");
    show_performance_analysis(&analysis);
    
    // 详细性能建议
    printf("\n=== 性能优化建议 ===\n");
    
    if (analysis.cpu_utilization_percent > 80) {
        printf("📌 CPU使用率很高 (%.1f%%),可能存在CPU瓶颈\n", 
               analysis.cpu_utilization_percent);
        printf("   建议:\n");
        printf("   - 考虑算法优化\n");
        printf("   - 检查是否存在无限循环\n");
        printf("   - 考虑并行处理\n");
    } else if (analysis.cpu_utilization_percent > 50) {
        printf("ℹ CPU使用率中等 (%.1f%%)\n", analysis.cpu_utilization_percent);
        printf("   建议:\n");
        printf("   - 监控CPU使用趋势\n");
        printf("   - 优化热点代码\n");
    } else {
        printf("✓ CPU使用率正常 (%.1f%%)\n", analysis.cpu_utilization_percent);
    }
    
    // I/O性能分析
    double io_ratio = (analysis.children_user_time_seconds + 
                      analysis.children_system_time_seconds) / 
                     analysis.wall_time_seconds;
    if (io_ratio > 0.3) {
        printf("\n📌 I/O操作占比较高 (%.1f%%)\n", io_ratio * 100);
        printf("   建议:\n");
        printf("   - 考虑异步I/O操作\n");
        printf("   - 优化文件访问模式\n");
        printf("   - 使用缓冲减少I/O次数\n");
    }
    
    // 并行效率分析
    if (analysis.children_user_time_seconds + analysis.children_system_time_seconds > 0) {
        printf("\n📊 子进程性能分析:\n");
        printf("   子进程总CPU时间: %.3f 秒\n", 
               analysis.children_user_time_seconds + analysis.children_system_time_seconds);
        printf("   平均每个子进程CPU时间: %.3f 秒\n",
               (analysis.children_user_time_seconds + analysis.children_system_time_seconds) / 2);
    }
    
    return 0;
}

int main() {
    return demo_performance_analyzer();
}

示例4:实时CPU监控 Link to heading

#include <sys/times.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
#include <time.h>
#include <signal.h>

/**
 * CPU监控数据结构
 */
typedef struct {
    time_t timestamp;
    clock_t ticks;
    struct tms tms_data;
    double cpu_usage_percent;
    double user_cpu_percent;
    double system_cpu_percent;
    double children_cpu_percent;
} cpu_monitor_data_t;

/**
 * CPU监控器结构
 */
typedef struct {
    cpu_monitor_data_t history[100];  // 历史数据
    int history_count;
    int max_history;
    long clk_tck;
    volatile int monitoring;
    pid_t target_pid;  // 监控特定进程(0表示当前进程)
} cpu_monitor_t;

/**
 * 初始化CPU监控器
 */
int init_cpu_monitor(cpu_monitor_t *monitor, pid_t target_pid) {
    memset(monitor, 0, sizeof(cpu_monitor_t));
    monitor->max_history = 100;
    monitor->clk_tck = sysconf(_SC_CLK_TCK);
    monitor->target_pid = target_pid;
    monitor->monitoring = 1;
    
    if (monitor->clk_tck == -1) {
        perror("获取系统滴答率失败");
        return -1;
    }
    
    printf("CPU监控器初始化完成\n");
    printf("  监控目标: %s\n", target_pid ? "特定进程" : "当前进程");
    printf("  系统滴答率: %ld 滴答/秒\n", monitor->clk_tck);
    
    return 0;
}

/**
 * 收集CPU使用数据
 */
int collect_cpu_data(cpu_monitor_t *monitor) {
    if (monitor->history_count >= monitor->max_history) {
        // 循环覆盖旧数据
        memmove(&monitor->history[0], &monitor->history[1], 
                sizeof(cpu_monitor_data_t) * (monitor->max_history - 1));
        monitor->history_count = monitor->max_history - 1;
    }
    
    cpu_monitor_data_t *current = &monitor->history[monitor->history_count];
    
    current->timestamp = time(NULL);
    current->ticks = times(&current->tms_data);
    
    if (current->ticks == (clock_t)-1) {
        perror("获取CPU时间失败");
        return -1;
    }
    
    // 计算CPU使用率(与前一个采样点比较)
    if (monitor->history_count > 0) {
        cpu_monitor_data_t *previous = &monitor->history[monitor->history_count - 1];
        clock_t ticks_diff = current->ticks - previous->ticks;
        
        if (ticks_diff > 0) {
            clock_t utime_diff = current->tms_data.tms_utime - previous->tms_data.tms_utime;
            clock_t stime_diff = current->tms_data.tms_stime - previous->tms_data.tms_stime;
            clock_t cutime_diff = current->tms_data.tms_cutime - previous->tms_data.tms_cutime;
            clock_t cstime_diff = current->tms_data.tms_cstime - previous->tms_data.tms_cstime;
            
            current->user_cpu_percent = (double)utime_diff / ticks_diff * 100;
            current->system_cpu_percent = (double)stime_diff / ticks_diff * 100;
            current->children_cpu_percent = (double)(cutime_diff + cstime_diff) / ticks_diff * 100;
            current->cpu_usage_percent = current->user_cpu_percent + 
                                        current->system_cpu_percent + 
                                        current->children_cpu_percent;
        } else {
            current->cpu_usage_percent = 0.0;
            current->user_cpu_percent = 0.0;
            current->system_cpu_percent = 0.0;
            current->children_cpu_percent = 0.0;
        }
    } else {
        // 第一次采样,无法计算使用率
        current->cpu_usage_percent = 0.0;
        current->user_cpu_percent = 0.0;
        current->system_cpu_percent = 0.0;
        current->children_cpu_percent = 0.0;
    }
    
    monitor->history_count++;
    return 0;
}

/**
 * 显示CPU监控数据
 */
void show_cpu_monitor_data(const cpu_monitor_t *monitor) {
    if (monitor->history_count == 0) {
        printf("暂无监控数据\n");
        return;
    }
    
    const cpu_monitor_data_t *latest = &monitor->history[monitor->history_count - 1];
    
    printf("=== CPU监控数据 ===\n");
    printf("采样时间: %s", ctime(&latest->timestamp));
    printf("CPU使用率: %.2f%%\n", latest->cpu_usage_percent);
    printf("  用户态: %.2f%%\n", latest->user_cpu_percent);
    printf("  系统态: %.2f%%\n", latest->system_cpu_percent);
    printf("  子进程: %.2f%%\n", latest->children_cpu_percent);
    
    // 显示详细时间信息
    printf("详细时间信息:\n");
    printf("  用户态时间: %.3f 秒\n", 
           (double)latest->tms_data.tms_utime / monitor->clk_tck);
    printf("  系统态时间: %.3f 秒\n", 
           (double)latest->tms_data.tms_stime / monitor->clk_tck);
    printf("  子进程用户态时间: %.3f 秒\n", 
           (double)latest->tms_data.tms_cutime / monitor->clk_tck);
    printf("  子进程系统态时间: %.3f 秒\n", 
           (double)latest->tms_data.tms_cstime / monitor->clk_tck);
}

/**
 * 显示历史趋势
 */
void show_cpu_trend(const cpu_monitor_t *monitor) {
    if (monitor->history_count < 2) {
        printf("数据不足,无法显示趋势\n");
        return;
    }
    
    printf("=== CPU使用率趋势 ===\n");
    printf("%-20s %-8s %-8s %-8s %-8s\n", 
           "时间", "总CPU%", "用户%", "系统%", "子进程%");
    printf("%-20s %-8s %-8s %-8s %-8s\n", 
           "----", "------", "----", "----", "-----");
    
    // 显示最近10个采样点
    int start_index = (monitor->history_count > 10) ? 
                     monitor->history_count - 10 : 0;
    
    for (int i = start_index; i < monitor->history_count; i++) {
        const cpu_monitor_data_t *data = &monitor->history[i];
        char time_str[20];
        strftime(time_str, sizeof(time_str), "%H:%M:%S", localtime(&data->timestamp));
        
        printf("%-20s %-8.1f %-8.1f %-8.1f %-8.1f\n",
               time_str,
               data->cpu_usage_percent,
               data->user_cpu_percent,
               data->system_cpu_percent,
               data->children_cpu_percent);
    }
}

/**
 * 模拟被监控的工作进程
 */
void work_process(int work_id) {
    printf("工作进程 %d (PID: %d) 启动\n", work_id, getpid());
    
    // 执行不同类型的工作
    for (int cycle = 0; cycle < 5; cycle++) {
        printf("工作进程 %d: 执行周期 %d\n", work_id, cycle + 1);
        
        // CPU密集型工作
        volatile long sum = 0;
        for (long i = 0; i < 50000000; i++) {
            sum += i;
        }
        printf("  CPU工作完成,结果: %ld\n", sum);
        
        // I/O工作
        char filename[64];
        snprintf(filename, sizeof(filename), "/tmp/work_%d_cycle_%d.tmp", work_id, cycle);
        FILE *fp = fopen(filename, "w");
        if (fp) {
            for (int i = 0; i < 10000; i++) {
                fprintf(fp, "工作数据 %d.%d\n", cycle, i);
            }
            fclose(fp);
            unlink(filename);
        }
        
        sleep(2);  // 休息一下
    }
    
    printf("工作进程 %d 完成\n", work_id);
    exit(work_id);
}

/**
 * 演示实时CPU监控
 */
int demo_real_time_cpu_monitoring() {
    cpu_monitor_t monitor;
    pid_t worker_pids[2];
    int worker_count = 2;
    
    printf("=== 实时CPU监控演示 ===\n");
    
    // 初始化监控器
    if (init_cpu_monitor(&monitor, 0) != 0) {
        return -1;
    }
    
    // 创建工作进程
    printf("创建 %d 个工作进程:\n", worker_count);
    for (int i = 0; i < worker_count; i++) {
        worker_pids[i] = fork();
        if (worker_pids[i] == 0) {
            work_process(i + 1);
        } else if (worker_pids[i] > 0) {
            printf("  工作进程 %d: PID=%d\n", i + 1, worker_pids[i]);
        } else {
            perror("创建工作进程失败");
            for (int j = 0; j < i; j++) {
                kill(worker_pids[j], SIGKILL);
            }
            return -1;
        }
    }
    
    // 开始监控
    printf("\n开始实时监控 (30秒):\n");
    time_t start_time = time(NULL);
    
    while (difftime(time(NULL), start_time) < 30) {
        // 收集CPU数据
        if (collect_cpu_data(&monitor) != 0) {
            printf("收集CPU数据失败\n");
            break;
        }
        
        // 每5秒显示一次详细信息
        if (((int)difftime(time(NULL), start_time)) % 5 == 0) {
            show_cpu_monitor_data(&monitor);
            
            // 每15秒显示一次趋势
            if (((int)difftime(time(NULL), start_time)) % 15 == 0) {
                show_cpu_trend(&monitor);
            }
            
            printf("---\n");
        }
        
        // 短暂休眠
        usleep(500000);  // 500ms
    }
    
    // 等待工作进程完成
    printf("等待工作进程完成:\n");
    for (int i = 0; i < worker_count; i++) {
        int status;
        pid_t finished_pid = waitpid(worker_pids[i], &status, 0);
        if (finished_pid > 0) {
            printf("  工作进程 %d (PID=%d) 已完成,退出状态: %d\n", 
                   WEXITSTATUS(status), finished_pid, WEXITSTATUS(status));
        }
    }
    
    // 显示最终监控结果
    printf("\n=== 最终监控结果 ===\n");
    
    // 收集最终数据
    collect_cpu_data(&monitor);
    show_cpu_monitor_data(&monitor);
    
    // 显示完整趋势
    printf("\n完整CPU使用率趋势:\n");
    show_cpu_trend(&monitor);
    
    // 统计分析
    if (monitor.history_count > 1) {
        double max_cpu = 0, min_cpu = 100, avg_cpu = 0;
        double total_cpu = 0;
        int valid_samples = 0;
        
        for (int i = 1; i < monitor.history_count; i++) {
            double cpu_usage = monitor.history[i].cpu_usage_percent;
            if (cpu_usage >= 0) {  // 有效数据
                if (cpu_usage > max_cpu) max_cpu = cpu_usage;
                if (cpu_usage < min_cpu) min_cpu = cpu_usage;
                total_cpu += cpu_usage;
                valid_samples++;
            }
        }
        
        if (valid_samples > 0) {
            avg_cpu = total_cpu / valid_samples;
            
            printf("\n=== 统计分析 ===\n");
            printf("CPU使用率统计:\n");
            printf("  最高使用率: %.2f%%\n", max_cpu);
            printf("  最低使用率: %.2f%%\n", min_cpu);
            printf("  平均使用率: %.2f%%\n", avg_cpu);
            
            if (avg_cpu > 80) {
                printf("  🚨 警告: 平均CPU使用率过高\n");
            } else if (avg_cpu > 60) {
                printf("  ⚠ 提醒: CPU使用率较高\n");
            } else {
                printf("  ✓ CPU使用率正常\n");
            }
        }
    }
    
    return 0;
}

int main() {
    return demo_real_time_cpu_monitoring();
}

示例5:进程资源使用统计 Link to heading

#include <sys/times.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
#include <time.h>
#include <sys/resource.h>

/**
 * 进程资源使用统计结构
 */
typedef struct {
    pid_t pid;
    char process_name[256];
    struct tms start_tms;
    struct tms end_tms;
    clock_t start_ticks;
    clock_t end_ticks;
    time_t start_time;
    time_t end_time;
    
    // CPU时间统计
    double user_time_seconds;
    double system_time_seconds;
    double children_user_time_seconds;
    double children_system_time_seconds;
    double total_cpu_time_seconds;
    double wall_clock_time_seconds;
    double cpu_utilization_percent;
    
    // 系统资源统计
    long max_rss_kb;      // 最大驻留集大小
    long page_faults;     // 页面错误次数
    long voluntary_ctxt_switches;   // 自愿上下文切换
    long nonvoluntary_ctxt_switches; // 非自愿上下文切换
} process_resource_stats_t;

/**
 * 初始化进程资源统计
 */
int init_process_resource_stats(process_resource_stats_t *stats, pid_t target_pid) {
    memset(stats, 0, sizeof(process_resource_stats_t));
    
    stats->pid = target_pid ? target_pid : getpid();
    stats->start_time = time(NULL);
    stats->start_ticks = times(&stats->start_tms);
    
    if (stats->start_ticks == (clock_t)-1) {
        perror("初始化进程资源统计失败");
        return -1;
    }
    
    // 获取进程名称
    char comm_path[256];
    snprintf(comm_path, sizeof(comm_path), "/proc/%d/comm", stats->pid);
    
    FILE *fp = fopen(comm_path, "r");
    if (fp) {
        if (fgets(stats->process_name, sizeof(stats->process_name), fp)) {
            // 移除换行符
            char *newline = strchr(stats->process_name, '\n');
            if (newline) *newline = '\0';
        }
        fclose(fp);
    } else {
        snprintf(stats->process_name, sizeof(stats->process_name), "process_%d", stats->pid);
    }
    
    printf("进程资源统计初始化:\n");
    printf("  进程ID: %d\n", stats->pid);
    printf("  进程名称: %s\n", stats->process_name);
    printf("  启动时间: %s", ctime(&stats->start_time));
    
    return 0;
}

/**
 * 完成进程资源统计
 */
int finish_process_resource_stats(process_resource_stats_t *stats) {
    long clk_tck = sysconf(_SC_CLK_TCK);
    
    stats->end_time = time(NULL);
    stats->end_ticks = times(&stats->end_tms);
    
    if (stats->end_ticks == (clock_t)-1) {
        perror("完成进程资源统计失败");
        return -1;
    }
    
    // 计算CPU时间
    clock_t utime_diff = stats->end_tms.tms_utime - stats->start_tms.tms_utime;
    clock_t stime_diff = stats->end_tms.tms_stime - stats->start_tms.tms_stime;
    clock_t cutime_diff = stats->end_tms.tms_cutime - stats->start_tms.tms_cutime;
    clock_t cstime_diff = stats->end_tms.tms_cstime - stats->start_tms.tms_cstime;
    
    stats->user_time_seconds = (double)utime_diff / clk_tck;
    stats->system_time_seconds = (double)stime_diff / clk_tck;
    stats->children_user_time_seconds = (double)cutime_diff / clk_tck;
    stats->children_system_time_seconds = (double)cstime_diff / clk_tck;
    stats->total_cpu_time_seconds = stats->user_time_seconds + 
                                   stats->system_time_seconds +
                                   stats->children_user_time_seconds + 
                                   stats->children_system_time_seconds;
    stats->wall_clock_time_seconds = (double)(stats->end_ticks - stats->start_ticks) / clk_tck;
    
    if (stats->wall_clock_time_seconds > 0) {
        stats->cpu_utilization_percent = (stats->total_cpu_time_seconds / 
                                         stats->wall_clock_time_seconds) * 100;
    }
    
    // 获取系统资源使用情况
    struct rusage usage;
    if (getrusage(RUSAGE_SELF, &usage) == 0) {
        stats->max_rss_kb = usage.ru_maxrss;  // 在Linux上以KB为单位
        stats->page_faults = usage.ru_majflt;
        stats->voluntary_ctxt_switches = usage.ru_nvcsw;
        stats->nonvoluntary_ctxt_switches = usage.ru_nivcsw;
    }
    
    return 0;
}

/**
 * 显示进程资源统计
 */
void show_process_resource_stats(const process_resource_stats_t *stats) {
    printf("=== 进程资源使用统计 ===\n");
    printf("进程信息:\n");
    printf("  进程ID: %d\n", stats->pid);
    printf("  进程名称: %s\n", stats->process_name);
    printf("  运行时间: %s 到 %s", 
           ctime(&stats->start_time), ctime(&stats->end_time));
    
    printf("\nCPU时间统计:\n");
    printf("  用户态时间: %.3f 秒\n", stats->user_time_seconds);
    printf("  系统态时间: %.3f 秒\n", stats->system_time_seconds);
    printf("  子进程用户态时间: %.3f 秒\n", stats->children_user_time_seconds);
    printf("  子进程系统态时间: %.3f 秒\n", stats->children_system_time_seconds);
    printf("  总CPU时间: %.3f 秒\n", stats->total_cpu_time_seconds);
    printf("  墙钟时间: %.3f 秒\n", stats->wall_clock_time_seconds);
    printf("  CPU利用率: %.2f%%\n", stats->cpu_utilization_percent);
    
    printf("\n系统资源统计:\n");
    printf("  最大内存使用: %ld KB (%.2f MB)\n", 
           stats->max_rss_kb, stats->max_rss_kb / 1024.0);
    printf("  主要页面错误: %ld\n", stats->page_faults);
    printf("  自愿上下文切换: %ld\n", stats->voluntary_ctxt_switches);
    printf("  非自愿上下文切换: %ld\n", stats->nonvoluntary_ctxt_switches);
    printf("  总上下文切换: %ld\n", stats->voluntary_ctxt_switches + 
           stats->nonvoluntary_ctxt_switches);
}

/**
 * 模拟不同类型的工作负载
 */
void simulate_workload(int workload_type, int intensity) {
    switch (workload_type) {
        case 1:  // CPU密集型
            printf("执行CPU密集型工作 (强度: %d)\n", intensity);
            volatile long sum = 0;
            for (long i = 0; i < intensity * 10000000L; i++) {
                sum += i * i;
            }
            printf("  CPU工作完成,结果: %ld\n", sum);
            break;
            
        case 2:  // I/O密集型
            printf("执行I/O密集型工作 (强度: %d)\n", intensity);
            for (int i = 0; i < intensity * 100; i++) {
                char filename[64];
                snprintf(filename, sizeof(filename), "/tmp/io_work_%d_%d.tmp", getpid(), i);
                
                FILE *fp = fopen(filename, "w");
                if (fp) {
                    for (int j = 0; j < 1000; j++) {
                        fprintf(fp, "测试数据 %d.%d\n", i, j);
                    }
                    fclose(fp);
                    unlink(filename);
                }
            }
            printf("  I/O工作完成\n");
            break;
            
        case 3:  // 内存密集型
            printf("执行内存密集型工作 (强度: %d)\n", intensity);
            size_t alloc_size = intensity * 1024 * 1024;  // MB
            char *buffer = malloc(alloc_size);
            if (buffer) {
                // 填充内存
                memset(buffer, 0xAA, alloc_size);
                // 访问内存
                volatile long checksum = 0;
                for (size_t i = 0; i < alloc_size; i += 1024) {
                    checksum += buffer[i];
                }
                printf("  内存工作完成,校验和: %ld\n", checksum);
                free(buffer);
            } else {
                printf("  内存分配失败\n");
            }
            break;
            
        default:
            printf("未知工作负载类型: %d\n", workload_type);
            break;
    }
}

/**
 * 演示进程资源使用统计
 */
int demo_process_resource_statistics() {
    process_resource_stats_t stats;
    long clk_tck = sysconf(_SC_CLK_TCK);
    
    printf("=== 进程资源使用统计演示 ===\n");
    printf("系统滴答率: %ld 滴答/秒\n", clk_tck);
    
    // 初始化统计
    if (init_process_resource_stats(&stats, 0) != 0) {
        return -1;
    }
    
    printf("\n开始执行不同类型的工作负载:\n");
    
    // 工作负载1: CPU密集型
    printf("\n1. CPU密集型工作:\n");
    simulate_workload(1, 5);
    
    // 工作负载2: I/O密集型
    printf("\n2. I/O密集型工作:\n");
    simulate_workload(2, 3);
    
    // 工作负载3: 内存密集型
    printf("\n3. 内存密集型工作:\n");
    simulate_workload(3, 100);
    
    // 混合工作负载
    printf("\n4. 混合工作负载:\n");
    for (int i = 0; i < 3; i++) {
        simulate_workload(1, 2);  // 轻量CPU工作
        simulate_workload(2, 1);   // 轻量I/O工作
        sleep(1);
    }
    
    // 完成统计
    if (finish_process_resource_stats(&stats) != 0) {
        return -1;
    }
    
    // 显示统计结果
    printf("\n");
    show_process_resource_stats(&stats);
    
    // 详细分析
    printf("\n=== 详细分析 ===\n");
    
    // CPU使用分析
    printf("CPU使用分析:\n");
    if (stats.cpu_utilization_percent > 80) {
        printf("  🚨 CPU使用率极高 (%.1f%%)\n", stats.cpu_utilization_percent);
        printf("     建议检查是否存在无限循环或算法效率问题\n");
    } else if (stats.cpu_utilization_percent > 50) {
        printf("  ⚠ CPU使用率较高 (%.1f%%)\n", stats.cpu_utilization_percent);
        printf("     建议优化热点代码\n");
    } else {
        printf("  ✓ CPU使用率正常 (%.1f%%)\n", stats.cpu_utilization_percent);
    }
    
    // 内存使用分析
    printf("\n内存使用分析:\n");
    if (stats.max_rss_kb > 1024 * 1024) {  // 超过1GB
        printf("  🚨 内存使用量巨大: %.2f GB\n", stats.max_rss_kb / (1024.0 * 1024.0));
        printf("     建议检查是否存在内存泄漏\n");
    } else if (stats.max_rss_kb > 100 * 1024) {  // 超过100MB
        printf("  ℹ 内存使用量较大: %.2f MB\n", stats.max_rss_kb / 1024.0);
        printf("     建议监控内存增长趋势\n");
    } else {
        printf("  ✓ 内存使用量正常: %.2f MB\n", stats.max_rss_kb / 1024.0);
    }
    
    // I/O效率分析
    printf("\nI/O效率分析:\n");
    double io_efficiency = (double)stats.voluntary_ctxt_switches / 
                          (stats.voluntary_ctxt_switches + stats.nonvoluntary_ctxt_switches + 1);
    if (io_efficiency > 0.8) {
        printf("  ✓ I/O效率良好 (%.1f%% 自愿切换)\n", io_efficiency * 100);
        printf("     表明程序很好地配合了I/O操作\n");
    } else {
        printf("  ℹ I/O效率一般 (%.1f%% 自愿切换)\n", io_efficiency * 100);
        printf("     可以考虑优化阻塞I/O操作\n");
    }
    
    // 性能建议
    printf("\n=== 性能优化建议 ===\n");
    printf("1. CPU优化:\n");
    printf("   - 分析CPU密集型代码段\n");
    printf("   - 考虑并行处理或算法优化\n");
    printf("   - 使用性能分析工具定位热点\n");
    
    printf("\n2. 内存优化:\n");
    printf("   - 监控内存使用峰值\n");
    printf("   - 及时释放不用的内存\n");
    printf("   - 考虑内存池或对象复用\n");
    
    printf("\n3. I/O优化:\n");
    printf("   - 使用缓冲减少I/O次数\n");
    printf("   - 考虑异步I/O操作\n");
    printf("   - 优化文件访问模式\n");
    
    return 0;
}

int main() {
    return demo_process_resource_statistics();
}

times 使用注意事项 Link to heading

系统要求: Link to heading

  1. POSIX兼容: 支持POSIX标准的系统
  2. 权限要求: 通常不需要特殊权限
  3. 架构支持: 支持所有主流架构

精度考虑: Link to heading

  1. 滴答精度: 受系统滴答率限制(通常100Hz)
  2. 累积误差: 长时间监控可能累积误差
  3. 采样频率: 高频采样可能影响被监控进程

错误处理: Link to heading

  1. 返回值检查: 必须检查返回值和errno
  2. 系统资源: 可能在资源不足时失败
  3. 进程状态: 目标进程终止时的行为

性能考虑: Link to heading

  1. 系统调用开销: 频繁调用有性能开销
  2. 内存使用: 历史数据存储需要内存
  3. 监控开销: 监控本身会消耗少量CPU资源

安全考虑: Link to heading

  1. 权限检查: 监控其他进程需要适当权限
  2. 资源限制: 避免过度消耗系统资源
  3. 数据保护: 监控数据的隐私和安全

最佳实践: Link to heading

  1. 合理采样: 选择适当的采样间隔
  2. 错误处理: 妥善处理各种错误情况
  3. 资源管理: 及时清理监控资源
  4. 数据持久化: 重要监控数据应持久化存储
  5. 报警机制: 设置合理的报警阈值

times函数特点 Link to heading

优点: Link to heading

  1. 标准兼容: POSIX标准函数,广泛支持
  2. 信息全面: 提供完整的CPU时间统计
  3. 性能良好: 系统调用开销小
  4. 易于使用: API简单直观

限制: Link to heading

  1. 精度限制: 受系统滴答率限制
  2. 实时性: 不是实时监控的最佳选择
  3. 跨进程: 监控其他进程需要权限
  4. 历史数据: 只能获取累积统计,不能获取瞬时值

相关函数对比 Link to heading

times vs clock: Link to heading

// times(): 获取进程CPU时间统计
struct tms tms_buf;
clock_t ticks = times(&tms_buf);

// clock(): 获取进程CPU时间
clock_t cpu_time = clock();

times vs getrusage: Link to heading

// times(): 基础CPU时间统计
struct tms tms_buf;
times(&tms_buf);

// getrusage(): 详细的资源使用情况
struct rusage usage;
getrusage(RUSAGE_SELF, &usage);

常见使用场景 Link to heading

1. 性能分析: Link to heading

// 分析程序CPU使用情况
struct tms start_tms, end_tms;
clock_t start_ticks = times(&start_tms);
// 执行程序
clock_t end_ticks = times(&end_tms);
// 计算CPU时间差

2. 资源监控: Link to heading

// 监控进程资源使用
while (monitoring) {
    struct tms current_tms;
    clock_t current_ticks = times(&current_tms);
    // 分析CPU使用率
    sleep(1);
}

3. 系统管理: Link to heading

// 系统负载监控
struct tms system_tms;
clock_t system_ticks = times(&system_tms);
// 分析系统整体性能

总结 Link to heading

times 函数是Linux系统中重要的进程资源监控工具,提供了:

  1. 全面的CPU时间统计: 包括用户态、系统态和子进程时间
  2. 标准兼容性: 符合POSIX标准,广泛支持
  3. 简单易用: API设计直观,易于集成
  4. 性能监控: 适用于各种性能分析场景

通过合理使用 times 函数,可以构建功能强大的性能监控和分析工具。在实际应用中,需要注意精度限制、错误处理和性能影响等问题,选择合适的监控策略和采样频率。