linux内核纳秒精度时间,Linux时钟精度:毫秒?微妙?纳秒?
最近被内核时钟精度弄的很是郁闷。具体情况如下:
扫盲:1秒=1000毫秒=1000000微妙=1000000000纳秒
首先:linux有一个很重要的概念——节拍,它的单位是(次/秒)。2.6内核这个值是1000,系统中用一个HZ的宏表征这个值。同时有全局的jiffies变量,表征从开机以来经过的节拍次数(这里面还有故事,后面说,先记住这个)。当然还有wall_jiffies的墙上jiffies来表示从 07-01-1970 到现在的节拍数。每个节拍里面执行一次时钟中断。就是说,它的精度是毫秒。
接着:内核中还有一个变量xtime表征系统的实际时间(墙上时间),定义如下。其中xtime.tv_sec以秒为单位,存放从Unix祖宗定的纪元时间(19700701)到现在的秒数。xtime.tv_nsec以纳秒为单位,记录从上一秒开始经过的纳秒数。就是说,它的精度是纳秒。
C
struct timespec xtime;
struct timespec{
time_t tv_sec; //秒
long tv_nsec; //纳秒
};
1
2
3
4
5
6
structtimespecxtime;
structtimespec{
time_ttv_sec;//秒
longtv_nsec;//纳秒
};
最后:linux提供一个gettimeofday的系统调用,它会返回一个timeval的结构体,定义如下。解释同上,tv_sec代表墙上时间的秒,tv_usec表示从上一秒到现在经过的微秒数。就是说,它的精度是微妙。
C
struct timeval{
long tv_sec; //秒
long tv_usec; //微妙
};
1
2
3
4
structtimeval{
longtv_sec;//秒
longtv_usec;//微妙
};
精彩的来了:
1. 内核中的xtime会在每个时钟中断的时候被更新一次,也就是每个节拍更新一次。你妹!!每毫秒更新一次怎么能冒出来纳秒的精度??而且,内核还有可能丢失节拍。怎么能是纳秒??
2. 各种书上说,gettimeofday系统调用是读取的xtime的值。日,为啥读出来之后精度丢了?变成微妙了?
寻寻觅觅终于理清了故事:
针对问题1:在linux启动的时候,一个节拍的时间长度还会以纳秒为单位初始化到tick_nsec中,初始化值为999848ns,坑爹啊!不到一毫秒!节拍大约为1000.15Hz。靠!实际的节拍竟然不是准确的1000!所以在每个时钟中断通过wall_jiffies去更新xtime的时候得到的就是一个以纳秒为最小单位的的值。所以!xtime的粒度应该是不到1毫秒,也就是精度是不到1毫秒。
针对问题2:gettimeday系统调用的读xtime代码部分如下:
C
do{
unsigned long lost;
seq = read_seqbegin(&xtime_lock);
usec = timer->get_offset(); //在计时器中取从上一次时钟中断到现在的微秒数
lost = jiffies - wall_jiffies;
if(lost)
usec += lost*(1000000/HZ); //HZ是节拍宏,值1000
sec = xtime.tv_sec;
usec += (xtime.tv_nsec/1000); //由纳秒转为微妙
}while(read_seqretry(&xtime_lock, seq))
1
2
3
4
5
6
7
8
9
10
11
12
do{
unsignedlonglost;
seq=read_seqbegin(&xtime_lock);
usec=timer->get_offset();//在计时器中取从上一次时钟中断到现在的微秒数
lost=jiffies-wall_jiffies;
if(lost)
usec+=lost*(1000000/HZ);//HZ是节拍宏,值1000
sec=xtime.tv_sec;
usec+=(xtime.tv_nsec/1000);//由纳秒转为微妙
}while(read_seqretry(&xtime_lock,seq))
while部分使用了seg锁,只看中间的就好了。加了注释之后就很清晰了。由于节拍可能会丢失,所以lost是丢失的节拍数(不会很多)。至于计时器就比较麻烦了,timer可能有下面四种情况。
a. 如果cur_timer指向timer_hpet对象,该方法使用HPET定时器——Inter与Microsoft开发的高精度定时器频率至少10MHz,也就是说此时可提供真正的微妙级精度。
b. 如果cur_timer指向timer_pmtmr对象,该方法使用ACPI PMT计时器(电源管理定时器)平率大约3.58MHz,也就是说也可以提供真正的微妙级精度。
c. 如果cur_timer指向timer_tsc对象,该方法使用时间戳计数器,内置在所有8086处理器,每个CPU时钟,计数器增加一次,频率就是CPU频率,所以timer精度最高。完全可以胜任微妙级的精度。
d. 如果cur_timer指向timer_pit对象,该方法使用PIT计数器,也即是最开始提到的节拍计数,频率大概是1000Hz,此时显然不能提供精度达到微妙的时间。所以只有这种情况是假毫秒精度!
综上:如果使用gettimeofday系统调用,只要不要使用节拍计数器就可以保证达到微妙精度的时间(刨除进程上下文时间误差)。至于网上说的可以拿到纳秒精度的时间,看起来都是错的。除非通过修改内核,使用时间戳计数器实现。Over!
最后最后说一个事情:jiffies的定义的是4字节,你可能猜想它初始值是0。实际上,事实并非如此!linux中jiffies被初始化为0xfffb6c20,它是一个32位有符号数,正好等于-300 000。因此,计数器会在系统启动5分钟内溢出。这是为了使对jiffies溢出处理有缺陷的内核代码在开发阶段被发现,避免此类问题出现在稳定版本中。
参考《深入理解linux内核》
原文链接
linux内核纳秒精度时间,Linux时钟精度:毫秒?微妙?纳秒?相关推荐
- linux内核下获取系统时间,linux内核获取当前系统时间
转载自:http://blog.csdn.net/heanyu/article/details/6552578 7.2. 获知当前时间 内核代码能一直获取一个当前时间的表示, 通过查看 jifies ...
- 移植linux内核-映像文件,移植Linux内核-映像文件
版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明 http://tigerwang202.blogbus.com/logs/43927976.html 首先从Blackfin uCli ...
- linux 内核 课程,Linux内核分析课程-全面剖析Linux内核技术 揭开Linux内核的面纱 Linux内核学习视频教 ......
课程名称 Linux内核分析课程-全面剖析Linux内核技术 揭开Linux内核的面纱 Linux内核学习视频 课程目录 (1)\1, 计算机是如何工作的?:目录中文件数:0个 (2)\2, 操作系统 ...
- 【Linux 内核】编译 Linux 内核 ① ( 下载指定版本的 Linux 内核源码 | Linux 内核版本号含义 | 主版本号 | 次版本号 | 小版本号 | 稳定版本 )
文章目录 一.下载 Linux 内核 1.下载最新版本 Linux 内核 2.下载指定版本 Linux 内核 二.Linux 内核版本号含义 一.下载 Linux 内核 1.下载最新版本 Linux ...
- linux内核分为四个子系统,linux操作系统的内核有哪几个子系统构成,简要说明各子系统的作用...
Linux是一个一体化内核(monolithic kernel)系统."内核"指的是一个提供硬件抽象层.磁盘及文件系统控制.多任务等功能的系统软件.一个内核不是一套完整的操作系统. ...
- Linux内核态之间进程通信,Linux 系统内核空间与用户空间通信的实现与分析[转载]...
[https://www.ibm.com/developerworks/cn/linux/l-netlink/index.html] 多数的 Linux 内核态程序都需要和用户空间的进程交换数据,但 ...
- Linux 编译时查找错误字符,编译Linux内核时出现“fatal error: linux/netfilter/xt_dscp: No such file or directory”...
编译Linux内核时出现"fatal error: linux/netfilter/xt_dscp: No such file or directory".下面开始查找原因. 第一 ...
- linux内核编译最详细,Linux内核编译详细教程,linux内核编译
Linux内核编译详细教程,linux内核编译 尝试编译下Linux-kernel 4.14.14,使用Ubuntu 16.04 64位 系统. kernel-4.14.14 内核文件约96MB,解压 ...
- 升级 Ubuntu Linux 内核的几种不同方法 | Linux 中国
转载自:升级 Ubuntu Linux 内核的几种不同方法 | Linux 中国 升级 Ubuntu Linux 内核的几种不同方法 | Linux 中国 译者/Ping Yang Linux 2 ...
- Linux内核编程(二)-----------Linux内核初探
写在前面:本篇主要介绍Linux内核的开发模式.linux代码的组成.vmlinux zImage uImage的区别,以及编译下内核. 正文: 一.Linux内核的开发模式 1.git:是一个分 ...
最新文章
- 微服务拆分,选型与演进
- secureCRT常用设置
- BSP for good 3d engine
- Java 给编译器看的注释--Annotation
- 一文详解微服务架构的数据设计
- LNK2019 无法解析的外部符号 __imp_CommandLineToArgvW,该符号在函数 WinMain 中被引用
- hadoop3.1.1 HA高可用分布式集群安装部署
- 电商购物APP UI 模板素材,充满时尚感的设计
- 软件架构设计的六大原则
- sizeo(结构体)的问题
- 26个字母与ASCII值对照表
- python 微信自动发图片,批量发送
- Mysql 计算年龄函数
- Python开发微信公众号
- VSCODE也可以进行gtest细粒度测试
- (七)DAC0832 数模转换芯片的应用 以及运算放大器的学习 01
- 佛蒙特大学给机器人口述「形态学」,使其「理解」人类指令
- Failed to decode response: zlib_decode(): data error Retrying with degraded;
- 获取UNIX系统时间
- 学生免费领取阿里云ECS云服务器并使用全过程(部署个人博客项目)