如何在 C++ 中获得以毫秒为单位的系统启动时间?

How do I get system up time in milliseconds in c++?

如何获取自系统启动以来的系统运行时间?我找到的只是自纪元以来的时间,没有别的。

例如,ctime 库中的 time() 之类的东西,但它只给了我自纪元以来的秒数。我想要类似 time() 的东西,但是自系统启动以来。

它是 OS 依赖的,并且已经在 Whosebug 上回答了几个系统。

#include<chrono> // for all examples :)

Windows ...

使用GetTickCount64()(分辨率通常为 10-16 毫秒)

#include <windows>
// ...
auto uptime = std::chrono::milliseconds(GetTickCount64());

Linux ...

... 使用 /proc/uptime

#include <fstream>
// ...
std::chrono::milliseconds uptime(0u);
double uptime_seconds;
if (std::ifstream("/proc/uptime", std::ios::in) >> uptime_seconds)
{
  uptime = std::chrono::milliseconds(
    static_cast<unsigned long long>(uptime_seconds*1000.0)
  );
}

... 使用 sysinfo(分辨率 1 秒)

#include <sys/sysinfo.h>
// ...
std::chrono::milliseconds uptime(0u);
struct sysinfo x;
if (sysinfo(&x) == 0)
{
  uptime = std::chrono::milliseconds(
    static_cast<unsigned long long>(x.uptime)*1000ULL
  );
}

OS X ...

... 使用 sysctl

#include <time.h>
#include <errno.h>
#include <sys/sysctl.h>
// ...
std::chrono::milliseconds uptime(0u);
struct timeval ts;
std::size_t len = sizeof(ts);
int mib[2] = { CTL_KERN, KERN_BOOTTIME };
if (sysctl(mib, 2, &ts, &len, NULL, 0) == 0)
{
  uptime = std::chrono::milliseconds(
    static_cast<unsigned long long>(ts.tv_sec)*1000ULL + 
    static_cast<unsigned long long>(ts.tv_usec)/1000ULL
  );
}

类 BSD 系统(或分别支持 CLOCK_UPTIMECLOCK_UPTIME_PRECISE 的系统)...

... 使用 clock_gettime (resolution see clock_getres)

#include <time.h>
// ... 
std::chrono::milliseconds uptime(0u);
struct timespec ts;
if (clock_gettime(CLOCK_UPTIME_PRECISE, &ts) == 0)
{
  uptime = std::chrono::milliseconds(
    static_cast<unsigned long long>(ts.tv_sec)*1000ULL + 
    static_cast<unsigned long long>(ts.tv_nsec)/1000000ULL
   );
}

有关于如何自定义日志消息的 boost example

作者在其中实现了一个简单的函数unsigned int get_uptime()来获取不同平台的系统正常运行时间,包括Windows、OSx、Linux以及BSD。

+1 已接受的答案。不错的调查。但是 OS X 答案不正确,我想在这里显示更正。

sysctl 函数在 OS X returns Unix Time the system was booted, not the time since boot. And on this system (and every other system too), std::chrono::system_clock also measures Unix Time 上输入 { CTL_KERN, KERN_BOOTTIME }。因此,只需减去这两个 time_points 即可获得自启动以来的时间。以下是修改已接受答案的 OS X 解决方案的方法:

std::chrono::milliseconds
uptime()
{
    using namespace std::chrono;
    timeval ts;
    auto ts_len = sizeof(ts);
    int mib[2] = { CTL_KERN, KERN_BOOTTIME };
    auto constexpr mib_len = sizeof(mib)/sizeof(mib[0]);
    if (sysctl(mib, mib_len, &ts, &ts_len, nullptr, 0) == 0)
    {
        system_clock::time_point boot{seconds{ts.tv_sec} + microseconds{ts.tv_usec}};
        return duration_cast<milliseconds>(system_clock::now() - boot);
    }
    return 0ms;
}

备注:

  • 最好chrono为您进行单位换算。如果您的代码中包含 1000(例如将秒转换为毫秒),请重写它以让 chrono 进行转换。
  • 如果编译,您可以依赖隐式计时持续时间单位转换是正确的。如果他们不编译,那就意味着你要求截断,你可以用 duration_cast.
  • 明确要求截断
  • 可以在函数中局部使用 using 指令 如果它使代码更具可读性。