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

时间:2022-09-06 08:12:23

How do I get system up time since the start of the system? All I found was time since epoch and nothing else.

如何从系统启动以来获得系统启动时间?我发现的只是时代以来的时间而已。

For example, something like time() in ctime library, but it only gives me a value of seconds since epoch. I want something like time() but since the start of the system.

例如,像ctime库中的time(),但它只给我一个自纪元以来秒的值。我想要像time()这样的东西但是从系统的开始。

3 个解决方案

#1


It is OS dependant and already answered for several systems on *.

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

Windows ...

using GetTickCount64() (resolution usually 10-16 millisecond)

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

Linux ...

... using /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)*1000ULL
  );
}

... using sysinfo (resolution 1 second)

#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 ...

... using 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-like systems (or systems supporting CLOCK_UPTIME or CLOCK_UPTIME_PRECISE respectively) ...

... using 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
   );
}

#2


+1 to the accepted answer. Nice survey. But the OS X answer is incorrect and I wanted to show the correction here.

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

The sysctl function with an input of { CTL_KERN, KERN_BOOTTIME } on OS X returns the 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. So one simply has to subtract these two time_points to get the time-since-boot. Here is how you modify the accepted answer's OS X solution to do this:

OS X上输入为{CTL_KERN,KERN_BOOTTIME}的sysctl函数返回系统引导的Unix时间,而不是引导后的时间。在这个系统(以及其他所有系统)上,std :: chrono :: system_clock也测量Unix时间。因此,只需减去这两个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;
}

Notes:

  • It is best to have chrono do your units conversions for you. If your code has 1000 in it (e.g. to convert seconds to milliseconds), rewrite it to have chrono do the conversion.
  • 最好让chrono为您完成单位转换。如果你的代码中有1000(例如将秒转换为毫秒),则重写它以使chrono进行转换。

  • You can rely on implicit chrono duration unit conversions to be correct if they compile. If they don't compile, that means you're asking for truncation, and you can explicitly ask for truncation with duration_cast.
  • 如果编译,您可以依赖隐式计时持续时间单位转换。如果它们不编译,这意味着你要求截断,并且你可以使用duration_cast明确要求截断。

  • It's ok to use a using directive locally in a function if it makes the code more readable.
  • 如果它使代码更具可读性,那么在函数中本地使用using指令是可以的。

#3


There is a boost example on how to customize logging messages.

有一个关于如何自定义日志消息的增强示例。

In it the author is implementing a simple function unsigned int get_uptime() to get the system uptime for different platforms including Windows, OSx, Linux as well as BSD.

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

#1


It is OS dependant and already answered for several systems on *.

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

Windows ...

using GetTickCount64() (resolution usually 10-16 millisecond)

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

Linux ...

... using /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)*1000ULL
  );
}

... using sysinfo (resolution 1 second)

#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 ...

... using 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-like systems (or systems supporting CLOCK_UPTIME or CLOCK_UPTIME_PRECISE respectively) ...

... using 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
   );
}

#2


+1 to the accepted answer. Nice survey. But the OS X answer is incorrect and I wanted to show the correction here.

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

The sysctl function with an input of { CTL_KERN, KERN_BOOTTIME } on OS X returns the 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. So one simply has to subtract these two time_points to get the time-since-boot. Here is how you modify the accepted answer's OS X solution to do this:

OS X上输入为{CTL_KERN,KERN_BOOTTIME}的sysctl函数返回系统引导的Unix时间,而不是引导后的时间。在这个系统(以及其他所有系统)上,std :: chrono :: system_clock也测量Unix时间。因此,只需减去这两个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;
}

Notes:

  • It is best to have chrono do your units conversions for you. If your code has 1000 in it (e.g. to convert seconds to milliseconds), rewrite it to have chrono do the conversion.
  • 最好让chrono为您完成单位转换。如果你的代码中有1000(例如将秒转换为毫秒),则重写它以使chrono进行转换。

  • You can rely on implicit chrono duration unit conversions to be correct if they compile. If they don't compile, that means you're asking for truncation, and you can explicitly ask for truncation with duration_cast.
  • 如果编译,您可以依赖隐式计时持续时间单位转换。如果它们不编译,这意味着你要求截断,并且你可以使用duration_cast明确要求截断。

  • It's ok to use a using directive locally in a function if it makes the code more readable.
  • 如果它使代码更具可读性,那么在函数中本地使用using指令是可以的。

#3


There is a boost example on how to customize logging messages.

有一个关于如何自定义日志消息的增强示例。

In it the author is implementing a simple function unsigned int get_uptime() to get the system uptime for different platforms including Windows, OSx, Linux as well as BSD.

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