通常,操作系统可以使用三种方法来表示系统的当前时间与日期:

①最简单的一种方法就是直接用一个64位的计数器来对时钟滴答进行计数。

②第二种方法就是用一个32位计数器来对秒进行计数,同时还用一个32位的辅助计数器对时钟滴答计数,之子累积到一秒为止。因为232超过136年,因此这种方法直至22世纪都可以让系统工作得很好。

③第三种方法也是按时钟滴答进行计数,但是是相对于系统启动以来的滴答次数,而不是相对于相对于某个确定的外部时刻;当读外部后备时钟(如RTC)或用户输入实际时间时,根据当前的滴答次数计算系统当前时间。

UNIX类操作系统通常都采用第三种方法来维护系统的时间与日期。

1 基本概念

首先,有必要明确一些Linux内核时钟驱动中的基本概念。

(1)时钟周期(clock cycle)的频率:8253/8254 PIT的本质就是对由晶体振荡器产生的时钟周期进行计数,晶体振荡器在1秒时间内产生的时钟脉冲个数就是时钟周期的频率。

Linux用宏CLOCK_TICK_RATE来表示8254 PIT的输入时钟脉冲的频率(在PC机中这个值通常是1193180HZ),该宏定义在include/asm-i386/timex.h头文件中:

#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */

(2)时钟滴答(clock tick):我们知道,当PIT通道0的计数器减到0值时,它就在IRQ0上产生一次时钟中断,也即一次时钟滴答。PIT通道0的计数器的初始值决定了要过多少时钟周期才产生一次时钟中断,因此也就决定了一次时钟滴答的时间间隔长度。

(3)时钟滴答的频率(HZ):也即1秒时间内PIT所产生的时钟滴答次数。类似地,这个值也是由PIT通道0的计数器初值决定的(反过来说,确定了时钟滴答的频率值后也就可以确定8254 PIT通道0的计数器初值)。Linux内核用宏HZ来表示时钟滴答的频率,而且在不同的平台上HZ有不同的定义值。对于ALPHA和IA62平台HZ的值是1024,对于SPARC、MIPS、ARM和i386等平台HZ的值都是100。该宏在i386平台上的定义如下(include/asm-i386/param.h):

#ifndef HZ

#define HZ 100

#endif

根据HZ的值,我们也可以知道一次时钟滴答的具体时间间隔应该是(1000ms/HZ)=10ms。

(4)时钟滴答的时间间隔:Linux用全局变量tick来表示时钟滴答的时间间隔长度,该变量定义在kernel/timer.c文件中,如下:

long tick = (1000000 + HZ/2) / HZ; /* timer interrupt period */

tick变量的单位是微妙(μs),由于在不同平台上宏HZ的值会有所不同,因此方程式tick=1000000÷HZ的结果可能会是个小数,因此将其进行四舍五入成一个整数,所以Linux将tick定义成(1000000+HZ/2)/HZ,其中被除数表达式中的HZ/2的作用就是用来将tick值向上圆整成一个整型数。

另外,Linux还用宏TICK_SIZE来作为tick变量的引用别名(alias),其定义如下(arch/i386/kernel/time.c):

#define TICK_SIZE tick

(5)宏LATCH:Linux用宏LATCH来定义要写到PIT通道0的计数器中的值,它表示PIT将没隔多少个时钟周期产生一次时钟中断。显然LATCH应该由下列公式计算:

LATCH=(1秒之内的时钟周期个数)÷(1秒之内的时钟中断次数)=(CLOCK_TICK_RATE)÷(HZ)

类似地,上述公式的结果可能会是个小数,应该对其进行四舍五入。所以,Linux将LATCH定义为(include/linux/timex.h):

/* LATCH is used in the interval timer and ftape setup. */

#define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */

类似地,被除数表达式中的HZ/2也是用来将LATCH向上圆整成一个整数。

2 表示系统当前时间的内核数据结构

作为一种UNIX类操作系统,Linux内核显然采用本节一开始所述的第三种方法来表示系统的当前时间。Linux内核在表示系统当前时间时用到了三个重要的数据结构:

①全局变量jiffies:这是一个32位的无符号整数,用来表示自内核上一次启动以来的时钟滴答次数。每发生一次时钟滴答,内核的时钟中断处理函数timer_interrupt()都要将该全局变量jiffies加1。该变量定义在kernel/timer.c源文件中,如下所示:

unsigned long volatile jiffies;

C语言限定符volatile表示jiffies是一个易该变的变量,因此编译器将使对该变量的访问从不通过CPU内部cache来进行。

②全局变量xtime:它是一个timeval结构类型的变量,用来表示当前时间距UNIX时间基准1970-01-01 00:00:00的相对秒数值。结构timeval是Linux内核表示时间的一种格式(Linux内核对时间的表示有多种格式,每种格式都有不同的时间精度),其时间精度是微秒。该结构是内核表示时间时最常用的一种格式,它定义在头文件include/linux/time.h中,如下所示:

struct timeval {

time_t tv_sec; /* seconds */

suseconds_t tv_usec; /* microseconds */

};

其中,成员tv_sec表示当前时间距UNIX时间基准的秒数值,而成员tv_usec则表示一秒之内的微秒值,且1000000>tv_usec>=0。

Linux内核通过timeval结构类型的全局变量xtime来维持当前时间,该变量定义在kernel/timer.c文件中,如下所示:

/* The current time */

volatile struct timeval xtime __attribute__ ((aligned (16)));

但是,全局变量xtime所维持的当前时间通常是供用户来检索和设置的,而其他内核模块通常很少使用它(其他内核模块用得最多的是jiffies),因此对xtime的更新并不是一项紧迫的任务,所以这一工作通常被延迟到时钟中断的底半部分(bottom half)中来进行。由于bottom half的执行时间带有不确定性,因此为了记住内核上一次更新xtime是什么时候,Linux内核定义了一个类似于jiffies的全局变量wall_jiffies,来保存内核上一次更新xtime时的jiffies值。时钟中断的底半部分每一次更新xtime的时侯都会将wall_jiffies更新为当时的jiffies值。全局变量wall_jiffies定义在kernel/timer.c文件中:

/* jiffies at the most recent update of wall time */

unsigned long wall_jiffies;

③全局变量sys_tz:它是一个timezone结构类型的全局变量,表示系统当前的时区信息。结构类型timezone定义在include/linux/time.h头文件中,如下所示:

struct timezone {

int tz_minuteswest; /* minutes west of Greenwich */

int tz_dsttime; /* type of dst correction */

};

基于上述结构,Linux在kernel/time.c文件中定义了全局变量sys_tz表示系统当前所处的时区信息,如下所示:

struct timezone sys_tz;

linux使用世界时间,linux世界里的时间相关推荐

  1. 关于Oracle SQL中系统时间和库里数据时间的比较

    取出表中和系统当前时间相差大于10分钟的数据 GXSJ为tb_jj_xcjk_mid表中字段,为更新时间, 注意时间格式要一致 如果要计算秒的话在*24*60后面再加上*60 也就是*24*60*60 ...

  2. Oracle全球化 —— 时间类型、时区与时间函数

    最近遇到一个表中数据时区不对的问题,排查思路一般是看表字段类型.看时区以及看插入时间的方法.Oracle官方文档<Database Globalization Support Guide> ...

  3. linux运行我的世界,我的世界1.8如何在linux的官服上玩

    如何在linux上玩我的世界呢?今天游戏园小编为大家带来了minecraft1.8初期在linu官服上玩我的世界教程,喜欢的朋友快来看看吧! 分成几部分.客户端本身.登录服务器.然后挂forge,上m ...

  4. linux玩我的世界java版_Ubuntu Linux 安装Minecraft我的世界

    Minecraft是一款自由度很高的沙盒游戏,<我的世界>.<当个创世神>.<麦块>.<我的手艺>等仅为非官方中文译名.并可以跨平台运行(Windows ...

  5. 3D魔幻手游【龙族世界】Linux手工端CDK授权后台安卓端详细架设视频教程

    3D魔幻手游[龙族世界]Linux手工端CDK授权后台安卓端详细架设视频教程p3D魔幻手游 龙族世界 Linux手工端 CDK授权后台 安卓端 详细架设视频教程 ppimg src style flo ...

  6. linux进程时钟时间,Linux的时钟

    Linux的时钟 作者:linuxer 发布于:2017-5-17 18:55 分类:时间子系统 一.前言 时钟或者钟表(clock)是一种计时工具,每个人都至少有一块,可能在你的手机里,也可能佩戴在 ...

  7. linux脚本日期时间,Linux 日期和时间操作详解

    Linux 日期和时间操作详解 发布时间:2012-11-27 15:10:07   作者:佚名   我要评论 Linux将时钟分为系统时钟(System Clock)和硬件(Real Time Cl ...

  8. suse linux修改系统时间,linux时间和时区修改(附suse)

    1.查看系统时间 [root@test3 ~]# date Thu Dec 20 23:25:33 CST 2012 [root@test3 ~]# date +"%Y%m%d %H:%m: ...

  9. linux OS与SQL修改时区,系统时间

    linux修改系统时间和linux查看时区.修改时区的方法 一.查看和修改Linux的时区 1. 查看当前时区 命令 : "date -R" 2. 修改设置Linux服务器时区 方 ...

  10. 关于utc时间与格林威治时间(linux上获取系统时区及代码)

    关于utc时间与格林威治时间 协调世界时,又称世界统一时间,世界标准时间,国际协调时间,简称UTC.它从英文"Coordinated Universal Time"/法文" ...

最新文章

  1. java线程callback,Java线程之异步回调(Callback)
  2. 谈谈AI的ToB市场,我的新书《B端产品经理修炼手册》正式出版
  3. Java 并发编程73道面试题及答案 ——面试看这篇就够了!
  4. iphone xh5打开ppt预览_教你如何用iPhone拍全景照片
  5. 《妥协的完美主义—优秀产品经理的实践指南(卷一)》一2.4 分工常见的错误...
  6. 代码生成工具之界面快速生成
  7. c# datetime._C#| DateTime.GetHashCode()方法与示例
  8. 成功者都在用的“成功咒语”
  9. 单片机与普通微型计算机不同在于,单片机与普通计算机的不同之处在于什么,单片机与普通微型计算机的不同...
  10. MySql的用户管理权限
  11. 程序员相亲的血泪史,千万别做这些事情!
  12. ATT与intel汇编格式区分
  13. eplan单线原理图多线原理图_EPLAN-文本
  14. java飞机大战游戏
  15. 14届数独-真题标准数独-Day 5-20220120
  16. 贴片铝电容识别及型号_如何识别各种材质贴片电容
  17. 数据分析必看的oCPM/oCPC核心知识点
  18. 高速公路ETC卡签之我见1-概述
  19. 系统架构设计师论文历年考题(2015-2017)考前冲刺来一波真题
  20. SAP中销售订单计划行类别中请求/装配对物料需求计划的影响测试

热门文章

  1. 左神讲算法——二分法及其拓展
  2. LLVM一些编程语法语义特性
  3. MindSpore基准性能
  4. 摄像头和相机模型和内参原理
  5. Cookie和Session的区别与联系
  6. 2021年大数据Spark(五十三):Structured Streaming Deduplication
  7. 生成对抗网络(GAN)
  8. Django 验证码4.4
  9. Cocos Creator里cc.tween的stopAllActions() 和 repeatForever的用法
  10. Ubuntu 系统打开任务管理