我如何在C 的毫秒内获得系统的时间

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

本文关键字:时间 系统      更新时间:2023-10-16

自系统启动以来,如何获得系统上升时间?我发现的只是以来的时间,没有别的。

例如,在ctime库中的时间()之类的东西,但是自时代以来,它只给了我几秒钟的价值。我想要时间(),但是自系统的开始。

它是OS依赖的,并且已经针对stackoverflow上的多个系统回答。

#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(分辨率请参见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
   );
}

1对接受的答案。不错的调查。但是OS X答案不正确,我想在此处显示更正。

sysctl功能带有{ CTL_KERN, KERN_BOOTTIME }在OS X上的输入的功能返回系统的启动时间,而不是启动以来的时间。在此系统(以及其他所有系统)上,std::chrono::system_clock还测量了UNIX时间。因此,只需减去这两个time_point即可获得时间启动。这是您修改接受答案的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截断。
  • 可以在功能中使用指令在函数中使用,如果代码更可读。

有一个有关如何自定义记录消息的示例。

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