You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++中获取Linux进程的高精度real/user/sys时间?

在Linux/Posix下用C++实现高分辨率的real/user/sys时间统计

核心需求

  • 模拟time命令的输出效果,统计一段代码的实际时间(real)、用户态CPU时间(user)、内核态CPU时间(sys)
  • 要求user/sys时间的分辨率至少达到1ms,替代仅提供10ms分辨率的times()函数

可行接口方案

1. 使用<sys/resource.h>中的getrusage()函数

这是Posix标准接口,能提供远高于times()的CPU时间统计分辨率:

  • 函数原型:int getrusage(int who, struct rusage *usage);
  • 传入RUSAGE_SELF可获取当前进程的资源使用数据
  • struct rusage中的ru_utime(用户态时间)和ru_stime(内核态时间)为struct timeval类型,包含秒和微秒(μs)级数据,完全满足1ms分辨率要求

2. 结合C++11 chrono获取real时间

real时间即墙钟时间,推荐用std::chrono::steady_clock(不受系统时间调整影响)实现:

  • 通过steady_clock::now()记录计时的起始和结束点,计算差值即可得到精确的real时间

完整示例代码

#include <iostream>
#include <chrono>
#include <sys/resource.h>
#include <cstdio>

class Timer {
public:
    void start() {
        // 记录墙钟起始时间
        real_start = std::chrono::steady_clock::now();
        // 记录初始CPU时间数据
        getrusage(RUSAGE_SELF, &start_usage);
    }

    void stop() {
        // 记录墙钟结束时间
        real_end = std::chrono::steady_clock::now();
        // 记录结束CPU时间数据
        getrusage(RUSAGE_SELF, &end_usage);
    }

    // 模拟time命令格式输出统计结果
    void print() {
        // 计算real时间(转换为秒,保留三位小数)
        auto real_us = std::chrono::duration_cast<std::chrono::microseconds>(real_end - real_start).count();
        double real_sec = real_us / 1e6;

        // 计算user态时间
        double user_sec = (end_usage.ru_utime.tv_sec - start_usage.ru_utime.tv_sec) +
                          (end_usage.ru_utime.tv_usec - start_usage.ru_utime.tv_usec) / 1e6;

        // 计算sys态时间
        double sys_sec = (end_usage.ru_stime.tv_sec - start_usage.ru_stime.tv_sec) +
                         (end_usage.ru_stime.tv_usec - start_usage.ru_stime.tv_usec) / 1e6;

        printf("real    %.3fs\n", real_sec);
        printf("user    %.3fs\n", user_sec);
        printf("sys     %.3fs\n", sys_sec);
    }

private:
    std::chrono::steady_clock::time_point real_start, real_end;
    struct rusage start_usage, end_usage;
};

// 测试用耗时函数
void test_task() {
    for (long long i = 0; i < 1e9; ++i) {
        __asm__ volatile("nop");
    }
}

int main() {
    Timer timer;
    timer.start();
    test_task();
    timer.stop();
    timer.print();
    return 0;
}

关键说明

  • Linux 2.6及以上内核版本已支持getrusage()的微秒级统计,完全覆盖1ms分辨率需求
  • 若需统计子进程的CPU时间,可传入RUSAGE_CHILDREN到getrusage(),但仅能统计已终止的子进程数据
  • steady_clock是单调时钟,不会因系统时间修改(如NTP同步)出现时间回退,比system_clock更适合计时场景

内容的提问来源于stack exchange,提问作者rob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 09:25:27