linux内核纳秒精度时间,Linux时钟精度:毫秒?微妙?纳秒?

article/2025/9/20 23:49:19

54707bc970eb239cf7702e9cab60b482.png最近被内核时钟精度弄的很是郁闷。具体情况如下:

扫盲: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内核》

原文链接


http://chatgpt.dhexx.cn/article/YV3s35wq.shtml

相关文章

java 日期 纳秒_java8 ZonedDateTime 日期精度到纳秒

1秒 10E3毫秒 10E6 微妙 10E9 纳秒 使用java8 Instant 内部实际System.currentTimeMillis() 在模型上 可输出纳秒数据 重点是模型 时间戳转日期 public static ZonedDateTime ofInstant(Instant instant, ZoneId zone) { Objects.requireNonNull(instant, "instant&qu…

第九章:NAT(网络地址转换协议)

文章目录 一、NAT1、NAT介绍①公有网络地址②私有网络地址 2、NAT工作原理3、NAT功能 二、NAT的实现方式1、静态转换(static Translation)实验对比 2、动态转换2.1 ACL(访问控制列表)2.2 配置动态NAT实验效果 3、端口多路复用3.1 …

【NAT网络地址转换(私网公网地址、静态NAT、动态NAT、NAPT、Easy IP、NAT Server)】-20211215、20211216

目录 一、NAT产生背景 1.产生背景 2.私网地址、公网地址​ 私网IP地址,既可以一定上缓解ip的不足,在私网里,ip地址可以随意使用。 公网地址,在需要访问公网时,运用网络地址转换NAT技术,可以实现。 二…

什么是私网,公网?

我们常说的内网和外网,通常是相对于防火墙而言的,在防火墙内部叫做内网,反之就是外网。 在一定程度上外网等同于公网,内网等同于私网。公网地址 公网地址是指在因特网上直接可达的地址,如果你有一个公网地址&#xff0…

NAT——公私网地址转换

NAT—网络地址转换 NAT NAT又称为网络地址转换,用于实现私有网络和公有网络之间的转换 私有和公有网络地址 公有网络地址是指互联网上全球唯一的IP地址 私有网络地址是指内部网络或者主机的IP地址 IANA(互联网数字分配机制)规定将下列的IP地…

公网地址和私网地址问题

服务器映射用于将内网服务器的私网地址映射为公网地址,供Internet用户访问。选择“静态映射”类型可以将每一台服务器映射成一个独立的公网IP地址。“服务器负载均衡”类型可以将多台服务器映射成同一个公网地址,Internet用户在访问这个公网地址时&#…

私网地址与Internet地址

一、A、B、C三类地址 可用地址范围备注A类1.0.0.1-126.255.255.254B类128.1.0.1-191.255.255.254C类192.0.1.1-223.255.255.254D类224.0.0.1-239.255.255.254D类为多播地址 说明: 1. 每一个地址都是用网络位主机位组成的。 2. 全0的和全1的网络位和主机位都要去掉…

计算机网络 网络层 私网地址和公网地址及子网划分

公网地址 公有地址分配和管理由Inter NIC(Internet Network Information Center 因特网信息中心)负责。各级ISP使用的公网地址都需要向Inter NIC提出申请,有Inter NIC统一发放,这样就能确保地址块不冲突。 私网地址(不…

为什么百度查到的ip和ipconfig查到的不一样;详解公网Ip和私网ip;详解网络分类ABC;

IP可以分为Public IP 和 Private IP,出现这种规划的原因在于IPv4所能表示的IP太少而电脑太多以至于不够用,然而只有Public IP才能直接连接上网络,所以对于那些公司,学校,政府机构等场所,就可以集中使用私有的IP进行管理…

挑战华为社招:掌握数据库其实很容易

前言 我的一个朋友,开发四年了,没跳过槽,四年时间也不过是从最开始的10K涨到了15K,经常和我吐槽工资低。去年8月份左右开始了他“骑驴找马”的行动,从各种地方找学习资料、刷面试题。值得庆幸的是,他出去找工作时疫情还不严重,异常顺利的面进了蚂蚁,薪资更是翻了几倍。…

javaspringboot面试,挑战华为社招

前言 redis简单来说 就是一个数据库,不过与传统数据库不同的是 redis 的数据是存在内存中的,所以存写速度非常快,因此 redis 被广泛应用于缓存方向。另外,redis 也经常用来做分布式锁。redis 提供了多种数据类型来支持不同的业务…

挑战华为社招:不止面试题,笔记源码统统都有,最强技术实现

前言 说起来开始进行面试是11月倒数第二周,上午9点,我还在去公司的公交上,突然收到蚂蚁的面试电话,其实算不上真正的面试。面试官只是和我聊了下他们在做的事情(主要是做双十一这里大促的稳定性保障,偏中间…

挑战华为社招:字节跳动上千道精选面试题还不刷起来

前言 成为优秀的架构师是大部分初中级工程师的阶段性目标。优秀的架构师往往具备七种核心能力:编程能力、调试能力、编译部署能力、性能优化能力、业务架构能力、在线运维能力、项目管理能力和规划能力。 这几种能力之间的关系大概如下图。编程能力、调试能力和编…

华为社招面试

工作第三年,在某招聘软件上填写简历后接到华为HR面试邀请,面试部门为运营商路由器,网上查看岗位相关要求之后发现与自己十分不匹配,不过机会难得,所以决定抱着学习的态度去参加面试。 2018年3月3号周六前往华为北研所Q…

华为社招技术二面,总结复盘

点击上方“Java基基”,选择“设为星标” 做积极的人,而不是积极废人! 源码精品专栏 原创 | Java 2020 超神之路,很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析网络应用框架 Netty 源码解析消息中间件 RocketMQ 源码解析数…

华为社招三面面经分享,现已拿到offer,定级D4对标17级

一面:(面试均是华为的开发,每轮面试完都有反问你想了解的) 修饰符和可见性抽象类抽象方法synchronized,volatile一些java类型相关的基础知识,比如springbuilder和springbuffer哪个线程安全为什么要使用spr…

华为社招面试(拿到offer)

前段时间华为主动联系我要不要面试,抱着试一下的心态接受了面试邀请,最后顺利拿到了offer,不过最终由于方方面面的原因还是没有去。 本文主要分享下,面试的大致过程。 1. 初步电话技术面试 主要问了下,项目C的后台开…

5年测试经验华为社招:半月3次面试,成功拿到Offer

背景经历 当时我工作近5年,明显感觉到了瓶颈期。具体来说,感觉自己用过很多测试框架和测试工具、做过一些测试开发、也有过高并发的性能测试,但是从技术深度上感觉不足,到后期时做事也没有明显挑战,完全适应了公司节奏…

华为Java社招面试经历详解【已拿到offer】

这篇文章主要介绍了华为Java社招面试经历,详细记录了华为java面试的流程、相关面试题与参考答案,需要的朋友可以参考下。 看看自己能答对多少,如果能回答70%的题目,就大胆去阿里以及各互联网公司试试身手吧。本篇建议大家收藏、备用~ 华为Java社招面试&…