我如何获取系统自启动以来的运行时间?我只能找到自纪元以来的时间,没有别的东西。
例如,像ctime库中的time()一样的东西,但它只给我自纪元以来的秒数。我想要类似于time()但是从系统启动以来的时间。
#include<chrono> // for all examples :)
GetTickCount64()
函数获取系统启动时间(分辨率通常为10-16毫秒)#include <windows>
// ...
auto uptime = std::chrono::milliseconds(GetTickCount64());
/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
(每秒一次的分辨率)#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
);
}
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
);
}
CLOCK_UPTIME
或CLOCK_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
);
}
static_cast<unsigned long long>(uptime_seconds*1000)
,因为uptime_seconds
包含毫秒,例如8084.13 * 1000 = 8084130 毫秒
而不是8084 * 1000 = 8084000 毫秒
。 - Mr.Angel+1 对被接受的答案。调查很好。但是 OS X 的答案是不正确的,我想在这里进行更正。
在 OS X 中,使用输入为 {CTL_KERN,KERN_BOOTTIME}
的 sysctl
函数返回系统启动时的 Unix 时间,而不是从启动以来的时间。并且在这个系统(以及其他所有系统)中,std::chrono::system_clock
也测量 Unix 时间。因此,只需减去这两个时间点即可得到自启动以来的时间。以下是如何修改被接受的答案中的 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
执行转换。chrono
持续时间单位转换可以编译,则可以依赖其正确性。如果无法编译,这意味着您要求截断,您可以使用duration_cast
显式地请求截断。system_clock
不是单调的,因此从 now-boot
中减去可能会导致错误甚至负值? - Adrian Mairesystem_clock
返回的值。严谨地说,在正常情况下,now-boot
可能会有一点错误,因为macOS没有完美的时钟。 - Howard Hinnant这里有一个关于如何自定义日志信息的boost示例。
其中,作者正在实现一个简单的函数unsigned int get_uptime()
,以获取不同平台(包括Windows、OSx、Linux和BSD)的系统运行时间。
GetTickCount
获取Windows时间, sysinfo
或 clock_gettime
获取Linux时间,以及 sysctl
获取OS X时间。 - Pixelchemist