跟涛哥一起学嵌入式 28:Linux下的时间管理和定时器编程

时间是我们生活中非常重要的一个概念,我们的生活处处离不开时间:你跟朋友定在晚上7点去吃火锅;你老板让你半个小时后去他办公室;还有一周就要放假过年了...。在现代社会中,没有时间的度量,我们的生活将寸步难行。除非你去终南山隐居,去过日出而作,日落而息的生活。

计算机中处处需要时间

在计算机系统中,也是处处需要时间,离开时间寸步难行:你的电影播放时间、系统日志log、QQ 微信聊天记录、电脑每周一次的杀毒、清理垃圾、软件更新,都需要时间。包括操作系统的任务调度,给每个进程分配运行时长,也需要时间。

生活中的时间可分为绝对时间和相对时间:公元2020年1月24日,你的电脑开机时间,这些可以算是绝对时间;万历15年、昨天今天和明天,则是相对时间。其实,相对时间和绝对时间并没有一个清晰的划分概念,一切时间可能都要以某一个时刻为起点,都是相对时间。绝对时间也是一种特殊的相对时间,因为大家都使用默认的参考起点,所以一般就看做绝对时间了。

你沐浴在温暖在阳光里,我在漆黑的夜里沉睡。由于地球自转的原因,世界各地的日落日出时间不一样,因此也引出了时区的概念:全球划分为24个时区,以伦敦的本初子午线为准,往东叫东X区,往西叫西X区。如伦敦时间凌晨0点,因为我们在东八区,太阳比伦敦早8个小时升起,所以我们的时间就是早上八点。

 

v2-c71fc94944961937829c48f1753624c7_b.jpg

伦敦的时间,也就是子午线0时区的时间,一般称为格林威治时间(GMT,Greenwich Mean Time),又称作世界协调时间( UTC,Coordinated Universal Time)。计算机中一般保存的就是这种世界标准时间,以1970年1月1日零时零分0秒为起点,记录到现在的秒数。但是世界各地的电脑显示的一般是本地时间,会将世界标准时间结合你本地电脑设置的时区,转换为本地时间并显示在电脑桌面的右下角。

 

时间的计量

戴过手表的同学可能都有过这种经历:每过一段时间就会发现自己的手表时间不准了,需要校准。为什么不准了呢?很简单,计时出现了误差。到哪里校准呢?很简单,每天晚上7点的新闻联播,很多人开始掏出自己的手表开始调时。为什么要以新闻联播为准呢?还得从计时器的发展历程说起。

古时候科技不发达,古人只能观天计时:日出日落、月圆月缺、春夏交替、四季轮回,发明了阳历和阴历。这种计时的精度只能以天来计算。后来古人发明了各种计时设备:日晷、沙漏、刻漏等,将计时精度推进了小时级别。但是这种计时器误差很大,四季太阳高度的变化、冬天夏天刻漏的滴水口的热胀冷缩,都会影响计时的精度。

 

v2-3b6bb96f1553d0b5a3a29b08600e0a49_b.jpg

后来欧洲人发明了机械钟,使用发条或单摆作为动力,把计时的精度推进到了秒级。比较有代表性的就是瑞士手表,可以说是机械钟的巅峰之作,风靡了几个世纪。

 

v2-e016642732155b75edf3e17869ee6084_b.jpg

电的出现和电子技术的发展,将计时器又推向了一个高度:采用晶振计时。给适应振荡器两边加电压,晶振就会发出规律的正弦波,再经过整形就可生成周期频率的方波,方波再讲过分频或倍频,就可以引入到CPU或SOC的内部,作为计时的时钟之源。

 

v2-711d8c1de5085dcea95c9b6d404be1b3_b.jpg

采用晶振计时的电子设备,一般精度可以达到微秒级别,多少年的计时误差可能只差1秒。现在的计算机或电子设备一般都采用这种晶振计时,给晶振两端加电压就可以让他永远振荡下去,唯一的缺陷就是当电脑或手机关机时就无法计时了。因此现在的计算机一般都有两个计时器,其中一个单独供电,比如我们电脑上的主板上就有一个CMOS电池给实时时钟供电,当电脑关机时,实时时钟仍可以继续计时。等你下次开机,你会发现时间一直很准确,这里面就有主板上的CMOS实时时钟的功劳。

随着时间流逝,不同计算机的计时也会出现或快或慢的误差。尤其是互联网时代,不同计算机之间进行通信,更需要时间同步。那该如何是好?不用担心,一种更精密的计时器出来了:铯原子钟。它是根据铯原子的原子跃迁产生振动磁场的振荡周期来作为原子时间的标准,误差是千万分之一秒。世界上第一个原子钟由美国国家物理实验室建造,作为世界标准标准时间之源。后来世界各地的实验室纷纷建立自己的实验室,作为本国的授时中心。如我国位于西安的中科院国家授时中心,新闻联播的实时报时就是以此为时间之源的。

 

v2-de70ad146231f8ddc74327f96734ea26_b.jpg

除了铯原子钟外,还有氢原子钟、铷原子钟等计时设备。在一些对时间要求比较高的航空航天、军事科研领域,一般会购买这种精密的计时设备,作为时间之源。

 

v2-17cece6c963d14f010d4ba815b4cf3f7_b.jpg

Linux中的时间管理

想对时间进行管理,光有硬件还不行,还需要软件的配合。在Linux系统中,内核中会对这些定时器进行设置,一般每隔 10ms 来一个时钟中断,即时钟节拍。每一次时钟到期产生中断后,内核中有一个叫jiffies的全局变量,用来记录系统启动以来发生中断的次数,因为时钟发生中断是周期性的,因此可以用来计时。

 

v2-5d2fe4ba5057aad9a878b325b483a275_b.jpg

为了计时准确,内核中使用另外一个全局变量 xtime 来记录实时时间:当系统启动后,内核会从CMOS上的实时时钟读取实时时间,保存到 xtime 变量中,随后随着时钟中断,不断更新 xtime 和 jiffies这两个值。关机时,内核再把实时时间 xtime 保存到CMOS主板上的实时时钟内,这样断电后,计算机仍可以使用独立电源实时计时。

 

时间管理和定时器编程

用户通过Linux操作系统提供的系统调用 或 C标准库函数的 API,可以方便的获取系统时间、设置系统时间,以及使用计算机的定时器进行编程,周期性地去做一些事情:比如定期杀毒、垃圾清理、软件升级等。

《Linux系统编程》第08期:时间管理和定时器编程,视频教程已经发布,将会给大家介绍Linux系统下关于时间的获取、设置、定时器编程的各种 API 接口的使用。CSDN学院搜课程名称或讲师名字“王利涛”即可。

 

发布了92 篇原创文章 · 获赞 38 · 访问量 3万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章