记录问题处理----Linux下休眠后,clock_gettime停止计时的问题

遇到问题:
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]

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值