clock_gettime参数中不同clock ID含义的差别

简介:

在分布式系统各个通信的过程中,有的应用场景需要把事件发生的时间戳放在消息中一起传递,接收端根据时间戳来判断事件发生的先后顺序。为此,就需要能够获取精确时间的函数,比如下面的代码:

 

clock_gettime(CLOCK_MONOTONIC, &ts);

    msg.hb_send_ts = ts;

    ret_val = msg_send(dest_id, MSG_OP_HBEAT, (char *)&msg, sizeof(msg));

 

此外,在性能统计的过程中,我们也需要设置固定的时间间隔,以便获取期间的运算次数或者IO数量。比如下面的代码:

   pthread_mutex_lock(&(info->stat_lock));

    if (info->stat_run != 0) {

        info->stat_run = 0;

        clock_gettime(CLOCK_MONOTONIC, &tv);

        tv.tv_sec += 1;     

        pthread_cond_timedwait(&(info->stat_thd_exist), &(info->stat_lock), &tv);

        pthread_mutex_unlock(&(info->stat_lock));

    }

 

上面的两个应用场景中都用到了clock_gettime()函数,问题是这种调用方法正确么?

 

这就要求对clock_gettime()的不同clk_id有深入的了解,根据个人的理解,下表列出了不同类型的区别:

wKioL1nLlp2RF0f8AADNrXRTYdk866.png 

这里需要补充的是:上面提到的NTP (NetWork Time Protocal)里后台会调用adjtime(),因此不收NTP影响也就不会受adjtime()函数影响。

 

在我们实际运行的Linux操作系统中,比如CentOS 7中, NTP服务chronyd默认会开启,用户可以参考下面的命令去检查:

[root@localhost ~]# systemctl status  chronyd

● chronyd.service - NTP client/server

   Loaded: loaded (/usr/lib/systemd/system/chronyd.service; enabled; vendor preset: enabled)

   Active: active (running) since Wed 2017-09-27 16:52:07 CST; 3h 9min ago

 Main PID: 1287 (chronyd)

   CGroup: /system.slice/chronyd.service

           └─1287 /usr/sbin/chronyd -u chrony

 

Sep 27 16:52:07 localhost.localdomain systemd[1]: Starting NTP client/server...

Sep 27 16:52:07 localhost.localdomain chronyd[1287]: chronyd version 1.29.1 starting

Sep 27 16:52:07 localhost.localdomain chronyd[1287]: Linux kernel major=3 minor=10 patch=0

Sep 27 16:52:07 localhost.localdomain chronyd[1287]: hz=100 shift_hz=7 freq_scale=1.00000000 nominal_tick=10000 slew_delta_tick=833 max_tick_bias=1000 shift_pll=2

Sep 27 16:52:07 localhost.localdomain chronyd[1287]: Frequency -1.497 +/- 1.312 ppm read from /var/lib/chrony/drift

Sep 27 16:52:07 localhost.localdomain systemd[1]: Started NTP client/server.

Sep 27 16:52:17 localhost.localdomain chronyd[1287]: Selected source 120.25.115.20

 

在此情况下,如果clk_id使用CLOCK_MONOTONIC,显然会受NTP的影响,这会导致时间的时间间隔不准。为此,根据上面的对比表,上面的列举的两个应用场景,应该使用CLOCK_MONOTONIC_RAW 。读者,如果对具体的差异感兴趣,可以在LInux下输入man clock_gettime()查看具体的描述信息。

 

据此举一反三,不但在读取时间或时间间隔的时候,我们需要考虑到不同始终类型是否受系统时间设置函数以及NTP的影响。在调用设置时间的函数的时候,也需要考虑到对系统各种时钟会带来何种改变,这样才能保证在多个软件模块组成的系统中,不会因为时间读取、时钟设置、NTP服务等带来误差甚至错误。

 

 








本文转自存储之厨51CTO博客,原文链接:http://blog.51cto.com/xiamachao/1969256 ,如需转载请自行联系原作者

相关文章
|
Python
如果一个变量没有"expire_time"属性
如果一个变量没有"expire_time"属性
71 3
|
1月前
|
存储 编解码 iOS开发
Python模块操作:time—Clock Time(一)
Python模块操作:time—Clock Time(一)
|
1月前
|
存储 iOS开发 MacOS
Python模块操作:time—Clock Time(二)
Python模块操作:time—Clock Time(二)
|
3月前
|
SQL Oracle 关系型数据库
深入解析 NOW() 与 CURRENT_DATE() 的区别
【8月更文挑战第31天】
166 0
|
4月前
|
存储 缓存 Serverless
函数计算操作报错合集之如何处理运行时报错:“Function time out after 600 seconds”
在使用函数计算服务(如阿里云函数计算)时,用户可能会遇到多种错误场景。以下是一些常见的操作报错及其可能的原因和解决方法,包括但不限于:1. 函数部署失败、2. 函数执行超时、3. 资源不足错误、4. 权限与访问错误、5. 依赖问题、6. 网络配置错误、7. 触发器配置错误、8. 日志与监控问题。
clock函数
clock函数
80 0
|
开发者
Alarm-Clock 实验过程|学习笔记
快速学习 Alarm-Clock 实验过程
229 0
Alarm-Clock 实验过程|学习笔记
设计一个名为Time的类,这个类包含:表示时间的数据域hour,minute和second
设计一个名为Time的类,这个类包含:表示时间的数据域hour,minute和second
322 0
|
关系型数据库
Psqlgresql Time function时间函数
Psqlgresql Time function时间函数 select now() 获取的时间为什么一直不变 pg中获取时间的方式有多种 如果放在事务中,now()获取的就是事务开始的时间,事务不结束,时间不变;而clock_timestamp()显示的时间会实时变化。
1337 0