Linux时间、定时器、时间中断超时处理
内核时间管理
Linux内核计时、延时函数与内核定时器
内核通过定时器(timer)中断来跟踪时间流
硬件定时器以周期性的间隔产生时间中断,这个间隔(即频率)由内核根据HZ来确定,HZ是一个与体系结构无关的常数。这个时间间隔通常取1ms到10ms.
jiffies计算器
2.1每次当定时器中断发生时,内核内部通过一个64位的变量jiffies_64做加一计数。
2.2驱动程序开发者通常访问的是jiffies变量,它是jiffes_64的低32位。
定时器与时间管理:
extern u64 __jiffy_data jiffies_64;
extern unsigned long volatile __jiffy_data jiffies;
内核超时处理
#include
unsigned long j, stamp_1, stamp_half, stamp_n;
while (time_before(jiffies, j1)){}
(1)内核中的时间概念
时间管理在linux内核中占有非常重要的作用。
相对于事件驱动而言,内核中有大量函数是基于时间驱动的。
有些函数是周期执行的,比如每10毫秒刷新一次屏幕;
有些函数是推后一定时间执行的,比如内核在500毫秒后执行某项任务。
要区分:
*绝对时间和相对时间
*周期性产生的事件和推迟执行的事件
周期性事件是由系统系统定时器驱动的
(2)HZ值
内核必须在硬件定时器的帮助下才能计算和管理时间。
定时器产生中断的频率称为节拍率(tick rate)。
在内核中指定了一个变量HZ,内核初始化的时候会根据这个值确定定时器的节拍率。
HZ定义在<asm/param.h>,在i386平台上,目前采用的HZ值是1000。
也就是时钟中断每秒发生1000次,周期为1毫秒。即:
#define HZ 1000
注意!HZ不是个固定不变的值,它是可以更改的,可以在内核源代码配置的时候输入。
不同的体系结构其HZ值是不一样的,比如arm就采用100。
如果在驱动中要使用系统的中断频率,直接使用HZ,而不要用100或1000 a.理想的HZ值 i386的HZ值一直采用100,直到2.5版后才改为1000。 提高节拍率意味着时钟中断产生的更加频繁,中断处理程序也会更频繁地执行。 带来的好处有: *内核定时器能够以更高的频率和更高的准确度运行 *依赖定时器执行的系统调用,比如poll()和select(),运行的精度更高 *提高进程抢占的准确度 (缩短了调度延时,如果进程还剩2ms时间片,在10ms的调度周期下,进程会多运行8ms。 由于耽误了抢占,对于一些对时间要求严格的任务会产生影响) 坏处有: *节拍率要高,系统负担越重。 中断处理程序将占用更多的处理器时间。
(3)jiffies
全局变量jiffies用于记录系统启动以来产生的节拍的总数。
启动时,jiffies初始化为0,此后每次时钟中断处理程序都会增加该变量的值。
这样,系统启动后的运行时间就是jiffies/HZ秒
jiffies定义于<linux/jiffies.h>中:
extern unsigned long volatile jiffies; jiffies变量总是为unsigned long型。
因此在32位体系结构上是32位,而在64位体系上是64位。
对于32位的jiffies,如果HZ为1000,49.7天后会溢出。
虽然溢出的情况不常见,但程序在检测超时时仍然可能因为回绕而导致错误。
linux提供了4个宏来比较节拍计数,它们能正确地处理节拍计数回绕。
#include <linux/jiffies.h>
#define time_after(unknown, known) // unknow > known
#define time_before(unknown, known) // unknow < known
#define time_after_eq(unknown, known) // unknow >= known
#define time_before_eq(unknown, known) // unknow <= known
unknown通常是指jiffies,known是需要对比的值(常常是一个jiffies加减后计算出的相对值)
例:
unsigned long timeout = jiffies + HZ/2; /* 0.5秒后超时 /
…
if(time_before(jiffies, timeout)){
/ 没有超时,很好 /
}else{
/ 超时了,发生错误 */
time_before可以理解为如果在超时(timeout)之前(before)完成 *系统中还声明了一个64位的值jiffies_64,在64位系统中jiffies_64和jiffies是一个值。
可以通过get_jiffies_64()获得这个值。 *使用
1
2
u64 j2;
j2 = get_jiffies_64();
(4)获得当前时间
驱动程序中一般不需要知道墙钟时间(也就是年月日的时间)。但驱动可能需要处理绝对时间。
为此,内核提供了两个结构体,都定义在<linux/time.h>:
a.
struct timeval {
time_t tv_sec; /* seconds /
suseconds_t tv_usec; / microseconds */
};
较老,但很流行。采用秒和毫秒值,保存了1970年1月1日0点以来的秒数
b.
struct timespec {
time_t tv_sec; /* seconds /
long tv_nsec; / nanoseconds */
};
较新,采用秒和纳秒值保存时间。
c.do_gettimeofday() 该函数用通常的秒或微秒来填充一个指向struct timeval的指针变量,原型如下:
#include <linux/time.h>
void do_gettimeofday(struct timeval *tv);
d.current_kernel_time()
该函数可用于获得timespec
#include <linux/time.h>
struct timespec current_kernel_time(void);
确定时间的延迟执行
设备驱动程序经常需要将某些特定代码延迟一段时间后执行,通常是为了让硬件能完成某些任务。
长于定时器周期(也称为时钟嘀嗒)的延迟可以通过使用系统时钟完成,而非常短的延时则通过软件循环的方式完成
(1)短延时
对于那些最多几十个毫秒的延迟,无法借助系统定时器。
系统通过软件循环提供了下面的延迟函数:
内核时间管理
(1)内核中的时间概念
时间管理在linux内核中占有非常重要的作用。
相对于事件驱动而言,内核中有大量函数是基于时间驱动的。
有些函数是周期执行的,比如每10毫秒刷新一次屏幕;
有些函数是推后一定时间执行的,比如内核在500毫秒后执行某项任务。
要区分:
*绝对时间和相对时间
*周期性产生的事件和推迟执行的事件
周期性事件是由系统系统定时器驱动的
(2)HZ值
内核必须在硬件定时器的帮助下才能计算和管理时间。
定时器产生中断的频率称为节拍率(tick rate)。
在内核中指定了一个变量HZ,内核初始化的时候会根据这个值确定定时器的节拍率。
HZ定义在<asm/param.h>,在i386平台上,目前采用的HZ值是1000。
也就是时钟中断每秒发生1000次,周期为1毫秒。即:
#define HZ 1000
注意!HZ不是个固定不变的值,它是可以更改的,可以在内核源代码配置的时候输入。
不同的体系结构其HZ值是不一样的,比如arm就采用100。
如果在驱动中要使用系统的中断频率,直接使用HZ,而不要用100或1000 a.理想的HZ值 i386的HZ值一直采用100,直到2.5版后才改为1000。 提高节拍率意味着时钟中断产生的更加频繁,中断处理程序也会更频繁地执行。 带来的好处有: *内核定时器能够以更高的频率和更高的准确度运行 *依赖定时器执行的系统调用,比如poll()和select(),运行的精度更高 *提高进程抢占的准确度 (缩短了调度延时,如果进程还剩2ms时间片,在10ms的调度周期下,进程会多运行8ms。 由于耽误了抢占,对于一些对时间要求严格的任务会产生影响) 坏处有: *节拍率要高,系统负担越重。 中断处理程序将占用更多的处理器时间。
(3)jiffies
全局变量jiffies用于记录系统启动以来产生的节拍的总数。
启动时,jiffies初始化为0,此后每次时钟中断处理程序都会增加该变量的值。
这样,系统启动后的运行时间就是jiffies/HZ秒
jiffies定义于<linux/jiffies.h>中:
extern unsigned long volatile jiffies; jiffies变量总是为unsigned long型。
因此在32位体系结构上是32位,而在64位体系上是64位。
对于32位的jiffies,如果HZ为1000,49.7天后会溢出。
虽然溢出的情况不常见,但程序在检测超时时仍然可能因为回绕而导致错误。
linux提供了4个宏来比较节拍计数,它们能正确地处理节拍计数回绕。
#include <linux/jiffies.h>
#define time_after(unknown, known) // unknow > known
#define time_before(unknown, known) // unknow < known
#define time_after_eq(unknown, known) // unknow >= known
#define time_before_eq(unknown, known) // unknow <= known
unknown通常是指jiffies,known是需要对比的值(常常是一个jiffies加减后计算出的相对值)
例:
unsigned long timeout = jiffies + HZ/2; /* 0.5秒后超时 /
…
if(time_before(jiffies, timeout)){
/ 没有超时,很好 /
}else{
/ 超时了,发生错误 */
time_before可以理解为如果在超时(timeout)之前(before)完成 *系统中还声明了一个64位的值jiffies_64,在64位系统中jiffies_64和jiffies是一个值。
可以通过get_jiffies_64()获得这个值。 *使用
1
2
u64 j2;
j2 = get_jiffies_64();
(4)获得当前时间
驱动程序中一般不需要知道墙钟时间(也就是年月日的时间)。但驱动可能需要处理绝对时间。
为此,内核提供了两个结构体,都定义在<linux/time.h>:
a.
struct timeval {
time_t tv_sec; /* seconds /
suseconds_t tv_usec; / microseconds */
};
较老,但很流行。采用秒和毫秒值,保存了1970年1月1日0点以来的秒数
b.
struct timespec {
time_t tv_sec; /* seconds /
long tv_nsec; / nanoseconds */
};
较新,采用秒和纳秒值保存时间。
c.do_gettimeofday() 该函数用通常的秒或微秒来填充一个指向struct timeval的指针变量,原型如下:
#include <linux/time.h>
void do_gettimeofday(struct timeval *tv);
d.current_kernel_time()
该函数可用于获得timespec
#include <linux/time.h>
struct timespec current_kernel_time(void);
确定时间的延迟执行
设备驱动程序经常需要将某些特定代码延迟一段时间后执行,通常是为了让硬件能完成某些任务。
长于定时器周期(也称为时钟嘀嗒)的延迟可以通过使用系统时钟完成,而非常短的延时则通过软件循环的方式完成
(1)短延时
对于那些最多几十个毫秒的延迟,无法借助系统定时器。
系统通过软件循环提供了下面的延迟函数:
Linux时间、定时器、时间中断超时处理相关推荐
- linux上点时间延时,Linux上时间和定时器
Linux下时间和定时器 http://blog.chinaunix.net/u1/35065/showart_1870601.html重点读了第三种方法.文章写得很好,加了一点点注释可参考http: ...
- Linux内核——定时器和时间管理
定时器和时间管理 系统定时器是一种可编程硬件芯片.它能以固定频率产生中断.该中断就是所谓的定时器中断.它所相应的中断处理程序负责更新系统时间,还负责执行须要周期性执行的任务. 系统定时器和时钟中断处理 ...
- linux 时间与定时器编程原理,浅析 Linux 中的时间编程和实现原理-嵌入式-火龙果软件工程...
引子 我们都生活在时间中,但却无法去思考它.什么是时间呢?似乎这是一个永远也不能被回答的问题.然而作为一个程序员,在工作中,总有那么几次我必须思考什么是时间.比如,需要知道一段代码运行了多久:要在 l ...
- linux ubuntu 18.04设置锁屏时间和用户登录超时时间
设置锁屏时间 设置用户登录超时时间 方法一: 1.针对所有用户 sudo vim /etc/profile //编辑环境变量文件 --------------- export TMOUT=0 //修改 ...
- linux驱动开发5 按键中断实验(定时器和中断)
led:IO的输出 :key:IO的输入 法一:直接读写IO 使用while(1)无限读取,但CPU占用达到了99.6%,所以不行 #include <linux/types.h>#inc ...
- Linux内核之时间系统
Linux内核之时间系统 1.Linux时间系统 (1)CMOS时钟 (2)系统时钟 (3)节拍数(jiffies) (4)墙上时间(xtime) 2.重要数据结构 (1)struct tk_read ...
- linux 多核 系统时钟,Linux中的时间
1. Linux中time相关概念 1.1 real time 指的是实际流逝的时间,又称为Wall Clock Time(墙上时间). 比如,time命令统计出的real time指的是该进程从开始 ...
- 高性能定时器--时间轮/多级时间轮
运行原理 指针指向轮子上的一个槽,轮子以恒定的速度顺时针转动,每转动一步就指向下一个槽(虚线指针指向的槽),每次转动称为一个tick,一个tick的时间称为时间轮的槽间隔slot interval,即 ...
- linux 不同用户时间,Linux时间子系统之(一):时间的基本概念
Linux时间子系统之(一):时间的基本概念 作者:linuxer 发布于:2014-12-23 12:22 分类:时间子系统 本文使用Q & A的方式来和大家以前探讨一下时间的基本概念 一. ...
最新文章
- 1120. Friend Numbers (20)
- sql随机查询数据语句(NewID(),Rnd,Rand(),random())
- Windows Server AppFabric Caching
- 【转载】Jsoup设置代理ip访问
- matlab闭式网络潮流计算,闭式网络潮流计算.ppt
- matlab软件编程求解方程实验报告,数学实验“线性方程组高斯消去法”实验报告内含matlab程序.doc...
- php之使用curl对百度orc进行文字识别(二维码识别同理)--base64编码方式(解决image format error)
- cornerstone 使用
- Java判断拼音的工具类
- 边缘检测——Roberts算子
- 谷歌浏览器不能用_正在用 Chrome 或 Edge 浏览器的你,不能错过这亿个好用插件...
- NTC功率型热敏电阻
- 本人想了解CPU原理,大家能否推荐几本关于学习CPU原理的书?
- win10系统蓝牙服务器,如何打开win10系统的蓝牙并进行设备添加
- java 状态模式 同步_多人联机射击游戏中的设计模式应用(二):观察者模式,单例模式,状态模式,适配器模式...
- 戴尔微型计算机3048,戴尔5460一体机拆解,戴尔3048一体机
- pythondjango教程_【秒懂】号称最为简明实用的Django上手教程
- 电影“防火墙” 引发的黑客攻击迅雷(转)
- 【ceph】ceph osd blacklist cep黑名单|MDS问题分析
- 阿里云下载镜像失败:ERROR: certificate common name “img.ucdl.pp.uc.cn” doesn’t match requested host name “mirr
热门文章
- 易经玄学诠释人的一生
- Unhandled Rejection (ChunkLoadError): Loading chunk mf-dep_vendors-node_modules_core-js_index_j
- 记笔记最好用的超高颜值软件之一!Typora 你值得拥有!
- 【MySQL】单行函数
- 知识付费内容靠什么“变现”
- awtk开发实践——学习篇27: guage_pointer(仪表指针控件)
- JAVA获取当前时间并作比较
- 苹果触控笔有必要买吗?好用不贵主动式电容笔推荐
- 阅读1.Mobility pattern recognition based prediction for the subway station related bike-sharing trips
- day03-svg标签