Linux内核时钟系统和定时器实现

带你走进linux 内核 定时器(timer)实现机制 定时器层是基于tick层(高精度定时器)之上的,是根据系统jiffies来触发的,精度相对比较低。利用定时器,我们可以设定在未来的某一时刻,触发一个特定的事件。经常,也会把这种低精度定时器称作时间轮(Timer Wheel)。在内核中,一个定时器是使用 timer_list 结构体来表示的: entry:所有的定时器都会根据到期的时间被分配到一组链表中的一个中,该字段是链表的节点成员。 expires:字段指出了该定时器的到期时刻,也就是期望定时器到期时刻的jiffies计数值。这是一个绝对值,不 阅读详情

1. Linux内核时钟系统和定时器实现

补充: 后来发现,以及wiki上说:core infrastructure support for high resolution timers has been accepted into the mainline kernel (in 2.6.21)
//——————-

Linux 2.6.16之前,内核只支持低精度时钟,内核定时器的工作方式:

  • 系统启动后,会读取时钟源设备(RTC, HPET,PIT…),初始化当前系统时间;
  • 内核会根据HZ(系统定时器频率,节拍率)参数值,设置时钟事件设备,启动tick(节拍)中断。HZ表示1秒种产生多少个时钟硬件中断,tick就表示连续两个中断的间隔时间。在我电脑上,HZ=250, 一个tick = 1/HZ, 所以默认一个tick为4ms。
cat /boot/config-`uname -r` | grep 'CONFIG_HZ='
CONFIG_HZ=250
  • 设置时钟事件设备后,时钟事件设备会定时产生一个tick中断,触发时钟中断处理函数,更新系统时钟,并检测timer wheel,进行超时事件的处理。

在上面工作方式下,Linux 2.6.16 之前,内核软件定时器采用timer wheel多级时间轮的实现机制,维护操作系统的所有定时事件。timer wheel的触发是基于系统tick周期性中断。
所以说这之前,linux只能支持ms级别的时钟,随着时钟源硬件设备的精度提高和软件高精度计时的需求,有了高精度时钟的内核设计。
Linux 2.6.16 ,内核支持了高精度的时钟,内核采用新的定时器hrtimer,其实现逻辑和Linux 2.6.16 之前定时器逻辑区别:

  • hrtimer采用红黑树进行高精度定时器的管理,而不是时间轮;
  • 高精度时钟定时器不在依赖系统的tick中断,而是基于事件触发。

旧内核的定时器实现依赖于系统定时器硬件定期的tick,基于该tick,内核会扫描timer wheel处理超时事件,会更新jiffies,wall time(墙上时间,现实时间),process的使用时间等等工作。
新的内核不再会直接支持周期性的tick,新内核定时器框架采用了基于事件触发,而不是以前的周期性触发。新内核实现了hrtimer(high resolution timer),hrtimer的设计目的,就是为了解决time wheel的缺点:

  • 低精度;timer wheel只能支持ms级别的精度,hrtimer可以支持ns级别;
  • Timer wheel与内核其他模块的高耦合性;

新内核的hrtimer的触发和设置不像之前在定期的tick中断中进行,而是动态调整的,即基于事件触发,hrtimer的工作原理:通过将高精度时钟硬件的下次中断触发时间设置为红黑树中最早到期的 Timer 的时间,时钟到期后从红黑树中得到下一个 Timer 的到期时间,并设置硬件,如此循环反复。
在高精度时钟模式下,操作系统内核仍然需要周期性的tick中断,以便刷新内核的一些任务。前面可以知道,hrtimer是基于事件的,不会周期性出发tick中断,所以为了实现周期性的tick中断(dynamic tick):系统创建了一个模拟 tick 时钟的特殊 hrtimer,将其超时时间设置为一个tick时长,在超时回来后,完成对应的工作,然后再次设置下一个tick的超时时间,以此达到周期性tick中断的需求。
引入了dynamic tick,是为了能够在使用高精度时钟的同时节约能源,,这样会产生tickless 情况下,会跳过一些 tick。这里只是简单介绍,有兴趣可以读kernel源码。
这里写图片描述
上图1是Linux 2.6.16以来内核定时器实现的结构,
新内核对相关的时间硬件设备进行了统一的封装,定义了主要有下面两个结构:

  • 时钟源设备(closk source device):抽象那些能够提供计时功能的系统硬件,比如 RTC(Real Time Clock)、TSC(Time Stamp Counter),HPET,ACPI PM-Timer,PIT等。不同时钟源提供的精度不一样,现在pc大都是支持高精度模式(high-resolution mode)也支持低精度模式(low-resolution mode)。
  • 时钟事件设备(clock event device):系统中可以触发 one-shot(单次)或者周期性中断的设备都可以作为时钟事件设备。

当前内核同时存在新旧timer wheel 和 hrtimer两套timer的实现,内核启动后会进行从低精度模式到高精度时钟模式的切换,hrtimer模拟的tick中断将驱动传统的低精度定时器系统(基于时间轮)和内核进程调度。

内核定时器系统增加了hrtimer之后,对于用户层开放的定时器相关接口基本都是通过hrtimer进行实现的,从内核源码可以看到:


    https://github.com/torvalds/linux/blob/master/kernel/time/hrtimer.c

    *  These timers are currently used for:
    *   - itimers
    *   - POSIX timers
    *   - nanosleep
    *   - precise in-kernel timing
    *

2. 用户层定时器API接口

上面介绍完linux内核定时器的实现后,下面简单说一下,基于内核定时器实现的,对用户层开放的定时器API:间隔定时器itimer和POSIX定时器。

2.1 常见定时功能的API:sleep系列

在介绍itimer和POSIX定时器之前,我们先看看我们经常遇到过具有定时功能的库函数API接口:

alarm()
sleep()
usleep()
nanosleep()
  • alarm:

alarm()函数可以设置一个定时器,在特定时间超时,并产生SIGALRM信号,如果不忽略或不捕捉该信号,该进程会被终止。

#include <unistd.h>
unsigned int alarm(unsigned int seconds);
                                              return:0或到期剩余秒数

那么alarm在是如何实现的?Glibc中alarm是基于间隔定时器itimer来实现的(文章后面会说到itimer是基于hrtimer实现的)。如下alarm在库函数下的实现,alarm调用了setitimer系统调用:

https://github.com/lattera/glibc/blob/master/sysdeps/unix/alarm.c

unsigned int 
alarm (seconds)
     unsigned int seconds;
{
  ...
  if (__s
浅析linux 内核 高精度定时器(hrtimer)实现机制(一) 在Linux内核中已经存在了一个管理定时器的通用框架。不过它也有很多不足,最大的问题是其精度不是很高。哪怕底层的定时事件设备精度再高,定时器层的分辨率只能达到Tick级别,按照内核配置选项的不同,在100Hz到1000Hz之间。但是,原有的定时器层由于实现教早,应用广泛,如果完全替换掉会引入大量代码改动。因此,Linux内核又独立设计出了一个叫高精度定时器层(High Resolution Timer)的框架,可以为我们提供纳秒级的定时精度,以满足对精确时间有迫切需求的应用程序或内核驱动程序。 阅读详情

相关推荐

Linux·定时器原理与使用

Linux定时器

m0_64560763的博客 906

Linux内核编程(九)Linux内核定时器

Linux内核中有一个宏HZ,这个宏用来表示一秒钟对应的节拍的数量。利用Linux内核中的这个宏,我们就可以把时间转换成节拍数。比如,定时一秒钟换成节拍数就是expires=jiffies+1*HZ,其中宏定义jiffies为系统当前时间对应的节拍数。宏HZ的值我们是可以设置的,也就是说一秒钟对应多少个节拍数我们是可以设置的。打开make menuconfig图形化配置界面进行设置,具体设置路径查看其它博客。

qq_1033275663的博客 2308

Linux内核时钟与定时器的实现与编程

在Linux内核中,时钟和定时器是非常重要的组件,它们提供了时间管理和事件调度的功能。时钟用于跟踪系统时间,而定时器用于触发特定的操作或事件。本文详细介绍了Linux内核中时钟和定时器的实现,并提供了相应的源代码示例。通过深入理解和使用时钟和定时器,开发人员可以更好地控制时间和事件流,提高系统的性能和可靠性。

CodeByte的博客 127

linux中的内核时钟

linux中的内核时钟

hqb_newfarmer的博客 889

从零做出可发布的2D冒险游戏!Unity全流程实战指南:从资源搭建到打包发布,新手也能跟着做

项目配置→资源导入→核心模块开发→关卡设计→调试→打包发布;玩家控制→敌人AI→道具系统→UI系统→游戏管理器→音效系统;新手开发重点:先实现核心玩法(移动、跳跃、攻击),再补充UI、音效、存档等辅助功能;调试是关键:每实现一个功能就测试,避免最后一堆bug难以定位。从零做一款完整的2D冒险游戏,能快速提升你的Unity综合能力——不仅能掌握C#编程、2D物理、UI系统,还能理解游戏开发的完整流程。先做出基础版,再慢慢迭代优化,你会发现游戏开发并没有想象中那么难。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1176

从零到一:银河麒麟OS下C#跨平台开发的避坑指南

本文详细介绍了在银河麒麟OS下进行C#跨平台开发的完整流程,从开发环境搭建到避坑指南。针对国产操作系统特性,提供了.NET Core安装、开发工具链配置、桌面应用开发及部署优化的实战经验,特别关注ARM架构适配和性能调优,帮助开发者高效应对国产化开发挑战。

weixin_29221753的博客 863

保姆级教程:用Adams/Car和Simulink搞定你的第一个整车联合仿真(附模型文件)

本文提供了一份详尽的Adams/Car与Simulink联合仿真教程,涵盖从环境配置到模型导出的全流程。通过实战案例解析,帮助工程师快速掌握多体动力学仿真与控制算法开发的集成技术,特别适合汽车工程领域的初学者。文章还包含常见问题解决方案和性能优化建议,助您高效完成整车联合仿真项目。

weixin_29663861的博客 337

AMESim柱塞泵建模全指南:从HCD库搭建到联合仿真

液压系统仿真中,轴向柱塞泵的建模始终是难点与热点。柱塞泵结构紧凑、功率密度高,在工程机械与航空航天领域应用广泛,然而其运动学与流体细节深度耦合,给仿真带来不小挑战。AMESim平台中的HCD库提供了一种从物理结构出发的建模思路,将柱塞泵分解为容积腔、节流口与机械约束等基础单元,从而真实刻画柱塞腔压力波动、配流特性和容积效率等关键行为,摆脱黑盒模型的局限。基于机理建模的仿真结果,可用于泵参数优化、故障特征分析以及控制策略验证。进一步结合AMESim与Simulink联合仿真,可以高效开发变量泵排量控制系统,研

weixin_29159441的博客 289

zedboard(5)spi轮询和中断

一个SPI可以有几个从设备 在程序中使用 s32 XSpiPs_SetSlaveSelect(XSpiPs *InstancePtr, u8 SlaveSel) 选择。其实就是吧对应设备的ss拉低。 备注:只选一个ss,可以不用指定。(感觉,还没测试) 这是xspips.c中定义的函数,发送和接收有 XSpiPs_Transfer 和 XSpiPs_PolledTransfer 两个函数,分别采用中断和轮询模式。    一、轮询模式 米联客参考代码,SpiPs_Init中部分和官方例程流程一样,Spi

Kiss丶小坏 5890

HyperLynx(十五)多板仿真

在对话框的“Design file#1”下拉列表中选择“B00,Mainboard”,在其下方的“Reference designators”列表中选择元器件“J1”,然后在“Designfile#2”下拉列表中选择“BO1、RAM1”,在其下方的“Refer ence designators”列表中选择元器件“J1”,单击“Insert”按钮,为这两个元器件建立互连映射。在“Assign Models”对话框中,选择“B00 Motherboard”,将“U16.B12”设置为输出。

小幽余生不加糖 5060

Level 4自动驾驶系统设计0——功能与场景0

摘要:当前智能驾驶系统开发存在应试思维误区,过度依赖NCAP标准测试而忽视真实物理世界的复杂工况。随着系统进入L4大模型时代,必须从离散测试转向应对无限连续的长尾场景。关键在于解决传感器输入质量(避免"垃圾进垃圾出"问题),通过逆向定义方法论确保前端数据高置信度。同时采用影子模式收集分歧数据流,结合条件接受机制动态调整感知权重,最终实现功能释放主权(FO)的100%安全闭环。本文揭示了如何为端到端智驾大模型建立物理红线,这是确保L4系统量产的底层法则。

Godspeed_zwh的博客 307

【人脸识别/轻量级模型】MobileFaceNet:适用于人脸识别的轻量级网络模型(文末附pytorch代码)

MobileFaceNet:用于人脸识别的轻量级网络模型

Roaddd的博客 6988

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

上一篇: 进程中的地址是从何而来
下一篇: TCP连接的建立和关闭详解
walker沃克
博客等级 码龄16年 208粉丝 60原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值