遇到问题:
Linux下休眠后,导致获取系统已启动时间错误,检查发现是clock_gettime停止计时的问题导致的。
代码片段:
DWORD GetTickCount()
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
}
了解与查找资料:
资料一:
函数: int clock_gettime(clockid_t clk_id, struct timespec *tp);
clockid_t: 用于指定计时时钟的类型,有以下几种类型:
CLOCK_REALTIME: 系统实时时间,从Epoch计时,可被设置更改。
CLOCK_MONOTONIC: 系统运行时间,从系统启动时开始计时,系统休眠时不再计时(NTP与硬件时钟有问题时会影响其频率,没有验证过)。
CLOCK_PROCESS_CPUTIME_ID: 本进程启动到此刻使用CPU的时间,当使用sleep等函数时不再计时。
CLOCK_THREAD_CPUTIME_ID: 本线程启动到此刻使用CPU的时间,当使用sleep等函数时不再计时。
CLOCK_MONOTONIC_RAW : 系统运行时间,从系统启动时开始计时,系统休眠时不再计时(NTP与硬件时钟有问题时不会影响其频率,没有验证过)。
CLOCK_REALTIME_COARSE: 系统实时时间,从Epoch计时,可被设置更改,速度更快精度更低。
CLOCK_MONOTONIC_COARSE: 系统运行时间,从系统启动时开始计时,速度更快精度更低,系统休眠时不再计时(NTP与硬件时钟有问题时会影响其频率,没有验证过)。
CLOCK_BOOTTIME: 与CLOCK_MONOTONIC类似
CLOCK_REALTIME_ALARM : 闹钟时间(应该休眠后继续计时,没验证过),系统实时时间,从Epoch计时,可被设置更改。
CLOCK_BOOTTIME_ALARM: 闹钟时间(应该休眠后继续计时,没验证过),系统运行时间,从系统启动时开始计时。
CLOCK_TAI: 原子钟的时间,与CLOCK_REALTIME类似,不可被更改,没有闰秒。
————————————————
版权声明:本文为CSDN博主「hrx-@@」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lang523493505/article/details/90043636
资料二:
CLOCK_BOOTTIME(Linux特有属性,Linux 2.6.39开始加⼊):
与CLOCK_MONOTONIC类似,⽽且该clock记录的时间包括系统挂起过程中所经过的时间。该clock为那些想要获取包括系统挂起时间⽽且不⽤为CLOCK_REALTIME(会受到settimeofday影响)所带来的并发症所困扰的应⽤,提供了解决⽅案。
原文链接:https://wenku.baidu.com/view/36db2d5a24284b73f242336c1eb91a37f0113248.html
资料三:
原文:
After some discussions with Jamie Lokier about some of the
drawbacks of CLOCK_MONOTONIC not incrementing during suspend
(see http://www.spinics.net/lists/linux-fsdevel/msg40272.html),
I wanted to see if we couldn’t provide a new clockid that would
allow applications that wanted to be aware of time passing during
suspend without having to deal with the inconsistencies of
CLOCK_REALTIME caused by calls to settimeofday.
So this patchset introduces CLOCK_BOOTTIME, which is identical
to CLOCK_MONOTONIC, but includes any time spent in suspend.
google译文:
在与 Jamie Lokier 讨论了一些
CLOCK_MONOTONIC 在挂起期间不递增的缺点
(见http://www.spinics.net/lists/linux-fsdevel/msg40272.html),
我想看看我们是否不能提供一个新的时钟ID
允许想要知道时间流逝的应用程序
暂停而不必处理不一致的情况
CLOCK_REALTIME 由调用 settimeofday 引起。
所以这个补丁集引入了 CLOCK_BOOTTIME,它是相同的
到 CLOCK_MONOTONIC,但包括挂起所花费的任何时间。
原文链接:https://lwn.net/Articles/420142/
结论:
也就是说,我使用CLOCK_BOOTTIME参数即可解决休眠导致的获取系统启动时间错误的问题
inline DWORD GetTickCount1()
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
}
inline DWORD GetTickCount2()
{
struct timespec ts;
clock_gettime(CLOCK_BOOTTIME, &ts);
return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
}
int main( int argc, char* argv[] )
{
DWORD dwTest1 = GetTickCount1();
DWORD dwTest2 = GetTickCount2();
fprintf( stdout, TEXT("check time dwTest1[%d] dwTest2[%d]\n"), dwTest1, dwTest2 );
}
测试一下:
linux-sny:/home # uptime
05:03 up 0:23, 1 个用户,平均负载:0.00, 0.02, 0.05
linux-sny:/home # ./testtime
check time dwTest1[1008671] dwTest2[1408671]