Linux内核——定时器和时间管理
定时器和时间管理
系统定时器是一种可编程硬件芯片。它能以固定频率产生中断。该中断就是所谓的定时器中断。它所相应的中断处理程序负责更新系统时间,还负责执行须要周期性执行的任务。
系统定时器和时钟中断处理程序是Linux系统内核管理机制中的中枢。
另外一个关注的焦点是动态定时器——一种用来推迟运行程序的工具。
比方说。假设软驱马达在一定时间内都未活动,那么软盘驱动程序会使用动态定时器关闭软驱马达。
内核能够动态创建或销毁动态定时器。
内核中的时间观念
内核在硬件的帮助下计算和管理时间。
硬件为内核提供一个系统定时器用以计算流逝的时间。
系统定时器以某种频率自行触发。产生时钟中断。进入内核时钟中断处理程序中进行处理。该频率能够通过编程预定,称为节拍率(tick rate)。
连续两次时钟中断的间隔时间称为节拍(tick)。它等于节拍率分之中的一个秒。
墙上时间和系统执行时间依据时钟间隔来计算。
节拍率HZ
节拍率(HZ)是时钟中断的频率,表示的一秒内时钟中断的次数。
比方 HZ=100 表示一秒内触发100次时钟中断程序。
提高节拍率中断产生更加频繁带来的优点:
提高时间驱动事件的解析度;
提高时间驱动事件的精确度;
内核定时器以更高的频度和精确度;
依赖顶上执行的系统调用poll()和select()能更高的精度执行;
系统时间測量更精细。
提高进程抢占的精确度;
提高节拍率带来的副作用:
中断频率增高系统负担添加;
中断处理程序占用处理器时间增多;
频繁打断处理器快速缓存;
jiffies
jiffies:全局变量,用来记录自系统启动以来产生的节拍总数。
启动时内核将该变量初始化为0。此后每次时钟中断处理程序添加该变量的值。每一秒钟中断次数HZ,jiffies一秒内添加HZ。系统执行时间 = jiffie/HZ.
jiffies用途:计算流逝时间和时间管理。
jiffies 变量总是无符号长整数(unsignedlong)。因此,在32位体系结构上是32位,在64位体系结构是64位,当 jiffies 的值超过它的最大存放范围后就会发生溢出,它的值会回绕到0。内核提供了四个宏来帮助比較节拍计数,它们能正确地处理节拍计数回绕情况。
硬时钟和定时器
实时时钟(RTC):用来持久存放系统时间的设备。即便系统关闭后,靠主板上的微型电池提供电力保持系统的计时。系统启动内核通过读取RTC来初始化墙上时间,改时间存放在xtime变量中。
系统定时器:内核定时机制。注冊中断处理程序,周期性触发中断。响应中断处理程序。
时钟中断处理程序
时钟中断处理程序可以划分为两个部分:体系结构相关部分和体系结构无关部分。与体系结构相关的例程作为系统定时器的中断处理程序而注冊到内核中,以便在产生时钟中断时,它可以对应地执行。
尽管处理程序的详细工作依赖于特定的体系结构,可是绝大多数处理程序最低限度都要执行例如以下工作:
1)获得 xtime_lock
锁。以便对訪问 jiffies_64
和墙上时间 xtime
进行保护。
2)须要时应答或又一次设置系统时钟。
3)周期性地使用墙上时间更新实时时钟。
4)调用体系结构无关的时钟例程:do_timer()。
中断服务程序主要通过调用与体系结构无关的例程 do_timer
运行以下的工作:
1)给 jiffies_64
变量添加 1
(这个操作即使是在 32
位体系结构上也是安全的,由于前面已经获得了 xtime_lock
锁)。
2)更新资源消耗的统计值。比方当前进程所消耗的系统时间和用户时间。
3)运行已经到期的动态定时器。
4)运行 scheduler_tick
函数。
5)更新墙上时间,该时间存放在 xtime
变量中。
6)计算平均负载值。
实际时间
实际时间就是现实中钟表上显示的时间。事实上内核中并不经常使用这个时间,主要是用户空间的程序有时须要获取当前时间。所以内核中也管理着这个时间。实际时间的获取是在开机后。内核初始化时从RTC读取的。
内核读取这个时间后就将其放入内核中的 xtime 变量中,而且在系统的执行中不断更新这个值。
定时器
定时器:管理内核时间的基础。推后或运行时间运行某些代码。
时器由结构 time_list
表示:
struct timer_list {
struct list_head entry; /* 定时器链表的入口 */
unsigned long expires; /* 以 jiffies 为单位的定时值 */
spinlock_t lock; /* 保护定时器的锁 */
void (*function)(unsigned long); /* 定时器处理函数 */
unsigned long data; /* 传给处理函数的长整形參数 */
struct tvec_t_base_s *base; /* 定时器内部值。用户不要使用 */
};
使用定时器:
struct timer_list my_timer; init_timer( &my_timer ); /* 初始化定时器 */ my_timer.expires = jiffies + delay; /* 定时器超时时的节拍数 */
my_timer.data = 0; /* 给定时器处理函数传入 0 值 */
my_timer.function = my_function; /* 定时器超时时调用的函数 */ add_timer( &my_timer ); /* 激活定时器 */
假设须要更改超时时间,能够调用 mod_timer
函数:mod_timer
函数无论 my_timer
是否已被激活,一旦从 mod_timer
返回,my_timer
都被激活并且设置了新的定时值。
假设调用时 my_timer
未被激活。该函数返回 0。否则返回 1。
假设须要停止定时器。能够使用 del_timer
和 del_timer_sync
函数。
延迟运行
内核代码除了使用定时器或下半部机制以外还须要其它方法来推迟运行任务。这样的推迟通常发生在等待硬件完毕某些工作时,并且等待的时间往往很短。
忙等待:
忙等待想要延迟的时间时节拍的整数倍,或者精确要求不高时才干够使用。
unsigned long delay = jiffies + 5 * HZ;
while( time_before( jiffies, delay ) )
cond_resched();
cond_resched函数将调度一个新程序投入执行,但它仅仅有在设置完 need_resched 标志后,才干生效。换句话说。该方法有效的条件是系统中存在更重要的任务须要执行。注意由于该方法须要调用调度程序,所以它仅仅能在进程上下文中使用。
短延迟
void udelay( unsigned long usecs );
void mdelay( unsigned long msecs );
前一个函数利用忙循环将任务延迟到指定的微秒数后执行,后者延迟指定的毫秒数。
schedule_timeout
该方法会让须要延迟执行的任务睡眠到指定的延迟时间耗尽后再又一次执行。但不保证睡眠时间正好等于指定的延迟时间——仅仅能尽量使睡眠时间接近指定的延迟时间。当指定的时间到期后。内核唤醒被延迟的任务并将其又一次放回执行队列。
/* 将任务设置为可中断睡眠状态 */
set_current_state( TASK_INTERRUPTIBLE );
/* 小睡一会儿,“s”秒后唤醒 */
schedule_timeout( s * HZ);
唯一的參数是延迟的相对时间,单位为 jiffies,注意在调用 schedule_timeout 函数前必须首先将任务设置为 TASK_INTERRUPTIBLE 或 TASK_UNINTERRUPTIBLE 两种状态之中的一个,否则任务不会睡眠。
因为schedule_timeout()函数须要调用调度程序。所以调用它的代码必须保证可以睡眠。
简而言之,调用代码必须处于进程上下文中,而且不能持有锁。
设置超时时间,在等待队列上睡眠
进程上下文中的代码为了等待特定事假发生,能够将自己放入等待队列。然后调用调度程序去运行新任务。
一旦事件发生后。内核调用 wake_up
函数唤醒在睡眠队列上的任务,使其又一次投入执行。
有时。等待队列上的某个任务可能即在等待一个特定事件到来,又在等待一个特定时间到来——就看谁来的更快。这样的情况下。代码能够简单的使用schedule_timeout()函数取代schedule()函数。这样一来。当希望指定时间到期。任务都会被唤醒。当然,代码须要检查被唤醒的原因——有可能是被事件唤醒。也有可能由于延迟的时间到期,还可能由于接收到了信号——然后运行对应的操作。
被激活或未被激活的定时器都能够使用。假设定时器还未被激活,该函数返回 0,否则返回 1。注意。不须要为已经超时的定时器调用该函数,由于它们会自己主动被删除。两者差别在于
del_timer_sync 会等待其它处理器上执行的定时器处理程序都退出才执行。所以 del_timer_sync
不能在中断上下文中使用。
但在安全性方面考虑。优先使用 del_timer_sync。
參考
http://www.cnblogs.com/bastard/archive/2012/09/21/2696393.html
http://www.cnblogs.com/pennant/archive/2012/12/31/2839545.html
http://www.cnblogs.com/wang_yb/archive/2013/05/10/3070373.html
Linux内核设计与实现
Linux内核——定时器和时间管理的更多相关文章
- Linux之定时器与时间管理 【转】
转自:http://blog.chinaunix.net/uid-23228758-id-154820.html 定时器与时间管理: 次,为一秒.一般的情况下编程者不要改变这个值,因为内核编很多代码都 ...
- 芯灵思Sinlinx A64开发板Linux内核定时器编程
开发平台 芯灵思Sinlinx A64 内存: 1GB 存储: 4GB 开发板详细参数 https://m.tb.cn/h.3wMaSKm 开发板交流群 641395230 Linux 内核定时器是内 ...
- 全志A33开发板Linux内核定时器编程
开发平台 * 芯灵思SinlinxA33开发板 淘宝店铺: https://sinlinx.taobao.com/ 嵌入式linux 开发板交流 QQ:641395230 Linux 内核定时器是内核 ...
- 芯灵思SinlinxA33开发板Linux内核定时器编程
开发平台 * 芯灵思SinlinxA33开发板 淘宝店铺: https://sinlinx.taobao.com/ 嵌入式linux 开发板交流 QQ:641395230 Linux 内核定时器是内核 ...
- Linux 内核的文件 Cache 管理机制介绍
Linux 内核的文件 Cache 管理机制介绍 http://www.ibm.com/developerworks/cn/linux/l-cache/ 1 前言 自从诞生以来,Linux 就被不断完 ...
- Linux 内核的文件 Cache 管理机制介绍-ibm
https://www.ibm.com/developerworks/cn/linux/l-cache/ 1 前言 自从诞生以来,Linux 就被不断完善和普及,目前它已经成为主流通用操作系统之一,使 ...
- 模仿linux内核定时器代码,用python语言实现定时器
大学无聊的时候看过linux内核的定时器,如今已经想不起来了,也不知道当时有没有看懂,如今想要模仿linux内核的定时器.用python写一个定时器,已经想不起来它的设计原理了.找了一篇blog,li ...
- 《Linux内核设计与实现》读书笔记(十一)- 定时器和时间管理【转】
转自:http://www.cnblogs.com/wang_yb/archive/2013/05/10/3070373.html 系统中有很多与时间相关的程序(比如定期执行的任务,某一时间执行的任务 ...
- Linux内核设计与实现 总结笔记(第十一章)定时器和时间管理
时间管理在内核中占用非常重要的地位,内核中有大量的函数都需要基于时间驱动的,内核对相对时间和绝对时间都非常需要. 一.内核中的时间概念 内核必须在硬件的帮助下才能计算和管理时间,系统定时器以某种频率自 ...
随机推荐
- SQLServer行转列
近期面试遇到了一道面试题.顿时有点迷糊,仅仅说出了思路.后来百度了一下.整理了一下思路,于是记录下来,方便以后学习.(面试题请參见附件) 相关的数据表: 1.Score表 2.[User]表 SQL语 ...
- android:改动PagerTabStrip中的背景颜色,标题字体的样式、颜色和图标以及指示条的颜色
1.改动PagerTabStrip中的背景颜色 我们在布局中直接设置background属性就可以: <android.support.v4.view.ViewPager android:id= ...
- 在Window和Linux下使用Zthread库
ZThread库是一个开源的跨平台高级面向对象的线性和sycnchronization 库,以运行POSIX 和Win32 系统中的C++程序. ZThread库的主页:http://zthread. ...
- shell 调试
感觉编写shell在查找错误的过程中,很让你崩溃,还好shell也提供了一些调试的方式: 语法检查 -n选项做语法检查,而不执行脚本 sh -n script_name.sh 启动 ...
- Apache+Django+Mysql环境配置
环境要求:Apache:2.2 Mysql:5.5 Django:1.5 python:2.7 首先下载mod_wsgi-win32-ap22py27-3.3.so 下载下来后,改名成mod_wsg ...
- 深刻:截获windows的消息并分析实例(DefWindowProc),以WM_NCHITTEST举例(Windows下每一个鼠标消息都是由 WM_NCHITTEST 消息产生的,这个消息的参数包含了鼠标位置的信息)
1,回调函数工作机制 回调函数由操作系统自动调用,回调函数的返回值当然也是返回给操作系统了. 2,截获操作系统发出的消息,截获到后,将另外一个消息返回给操作系统,已达到欺骗操作系统的目的. 下面还是以 ...
- [Windows Phone]AnimationHelper管理分散的Storyboard
问题描述: 在Windows Phone开发时候,可能存在这样的问题: 某一个控件需要一个特定的展现(这里假定是一个特定动画),那么我们会这么解决这个问题呢? 打开Blend,根据需求需求给控件添加动 ...
- UVa 10616 - Divisible Group Sums
称号:给你n数字.免去m一个,这使得他们可分割d.问:有多少种借贷. 分析:dp,D01背包. 背包整数分区. 首先.整点d.则全部数字均在整数区间[0,d)上: 然后,确定背包容量,最大为20*10 ...
- 改动file header (測)
--改动file header ------------------------------------------------------------------------- cd $ORACLE ...
- linux shell学习记录
1.shell脚本开始以 #! /usr/bin 这个叫做Shebang 这个指定解释器的路径 2.shell 一些配置在~/.bashrc中,运行的历史shell命令在~/.bash_history ...