How do I get system up time in milliseconds in c++?
It is OS dependant and already answered for several systems on stackoverflow.
#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*1000.0)
);
}
... 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
);
}
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.
+1 to the accepted answer. Nice survey. But the OS X answer is incorrect and I wanted to show the correction here.
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:
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 has1000
in it (e.g. to convert seconds to milliseconds), rewrite it to havechrono
do the conversion. - 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
. - It's ok to use a using directive locally in a function if it makes the code more readable.