为了使用它们, 尽管你不会需要知道内核定时器如何实现, 这个实现是有趣的, 并且值得 看一下它们的内部.

定时器的实现被设计来符合下列要求和假设:

  • 定时器管理必须尽可能简化.
  • 设计应当随着激活的定时器数目上升而很好地适应.
  • 大部分定时器在几秒或最多几分钟内到时, 而带有长延时的定时器是相当少见.
  • 一个定时器应当在注册它的同一个 CPU 上运行.

由内核开发者想出的解决方法是基于一个每-CPU 数据结构. 这个 timer_list 结构包括 一个指针指向这个的数据结构在它的 base 成员. 如果 base 是 NULL, 这个定时器没有 被调用运行; 否则, 这个指针告知哪个数据结构(并且, 因此, 哪个 CPU )运行它. 每- CPU 数据项在第 8 章的"每-CPU 变量"一节中描述.

无论何时内核代码注册一个定时器( 通过 add_timer 或者 mod_timer), 操作最终由 internal_add_timer 进行( 在 kernel/timer.c), 它依次添加新定时器到一个双向定时器 链表在一个关联到当前 CPU 的"层叠表" 中.

这个层叠表象这样工作: 如果定时器在下一个 0 到 255 jiffies 内到时, 它被添加到专 供短时定时器 256 列表中的一个上, 使用 expires 成员的最低有效位. 如果它在将来更 久时间到时( 但是在 16,384 jiffies 之前 ), 它被添加到基于 expires 成员的 9 - 14 位的 64 个列表中一个. 对于更长的定时器, 同样的技巧用在 15 - 20 位, 21 - 26 位, 和 27 - 31 位. 带有一个指向将来还长时间的 expires 成员的定时器( 一些只可能发生 在 64-位 平台上的事情 ) 被使用一个延时值 0xffffffff 进行哈希处理, 并且带有在过

去到时的定时器被调度来在下一个时钟嘀哒运行. (一个已经到时的定时器模拟有时在高
负载情况下被注册, 特别的是如果你运行一个可抢占内核).

当触发  run_timers, 它为当前定时器嘀哒执行所有挂起的定时器. 如果 jiffies 当前
是 256 的倍数, 这个函数还重新哈希处理一个下一级别的定时器列表到 256 短期列表, 可能地层叠一个或多个别的级别, 根据 jiffies 的位表示.

这个方法,
虽然第一眼看去相当复杂, 在几个和大量定时器的时候都工作得很好. 用来管 理每个激活定时器的时间独立于已经注册的定时器数目并且限制在几个对于它的
expires 成员的二进制表示的逻辑操作上. 关联到这个实现的唯一的开销是给 512 链表头的内存 ( 256 短期链表和 4 组 64 更长时间的列表)
-- 即 4 KB 的容量.

函数 run_timers, 如同
/proc/jitimer 所示, 在原子上下文运行. 除了我们已经描述 过的限制, 这个带来一个有趣的特性: 定时器刚好在合适的时间到时, 甚至你没有运行一
个可抢占内核, 并且 CPU 在内核空间忙. 你可以见到发生了什么当你在后台读

/proc/jitbusy 时以及在前台 /proc/jitimer. 尽管系统看来牢固地被锁住被这个忙等待
系统调用, 内核定时器照样工作地不错.

但是,
记住, 一个内核定时器还远未完善, 因为它受累于 jitter 和 其他由硬件中断引 起怪物, 还有其他定时器和其他异步任务. 虽然一个关联到简单数字 I/O
的定时器对于 一个如同运行一个步进马达或者其他业余电子设备等简单任务是足够的, 它常常是不合适 在工业环境中的生产系统. 对于这样的任务, 你将最可能需要依赖一个实时内核扩展.

linux 内核定时器的实现的更多相关文章

  1. 芯灵思Sinlinx A64开发板Linux内核定时器编程

    开发平台 芯灵思Sinlinx A64 内存: 1GB 存储: 4GB 开发板详细参数 https://m.tb.cn/h.3wMaSKm 开发板交流群 641395230 Linux 内核定时器是内 ...

  2. 全志A33开发板Linux内核定时器编程

    开发平台 * 芯灵思SinlinxA33开发板 淘宝店铺: https://sinlinx.taobao.com/ 嵌入式linux 开发板交流 QQ:641395230 Linux 内核定时器是内核 ...

  3. 芯灵思SinlinxA33开发板Linux内核定时器编程

    开发平台 * 芯灵思SinlinxA33开发板 淘宝店铺: https://sinlinx.taobao.com/ 嵌入式linux 开发板交流 QQ:641395230 Linux 内核定时器是内核 ...

  4. 模仿linux内核定时器代码,用python语言实现定时器

    大学无聊的时候看过linux内核的定时器,如今已经想不起来了,也不知道当时有没有看懂,如今想要模仿linux内核的定时器.用python写一个定时器,已经想不起来它的设计原理了.找了一篇blog,li ...

  5. Linux内核——定时器和时间管理

    定时器和时间管理 系统定时器是一种可编程硬件芯片.它能以固定频率产生中断.该中断就是所谓的定时器中断.它所相应的中断处理程序负责更新系统时间,还负责执行须要周期性执行的任务. 系统定时器和时钟中断处理 ...

  6. Linux内核 - 定时器

    #include <linux/timer.h> //头文件 struct timer_list mytimer; //定义变量 static void my_timer(unsigned ...

  7. Linux内核定时器struct timer_list

    1.前言 Linux内核中的定时器是一个很常用的功能,某些需要周期性处理的工作都需要用到定时器.在Linux内核中,使用定时器功能比较简单,需要提供定时器的超时时间和超时后需要执行的处理函数. 2.常 ...

  8. linux 内核定时器

    无论何时你需要调度一个动作以后发生, 而不阻塞当前进程直到到时, 内核定时器是给你 的工具. 这些定时器用来调度一个函数在将来一个特定的时间执行, 基于时钟嘀哒, 并且 可用作各类任务; 例如, 当硬 ...

  9. linux内核--定时器API

    /**<linux/timer.h> 定时器结构体 struct timer_list { ........ unsigned long expires; --内核希望定时器执行的jiff ...

随机推荐

  1. 删除指定节点Remove Nth Node From End of List

    Given a linked list, remove the nth node from the end of list and return its head. For example, Give ...

  2. Nginx教程(五) Nginx配置文件详解 (转)

    一. Nginx配置文件nginx.conf中文详解 #定义Nginx运行的用户和用户组 user www www; #nginx进程数,建议设置为等于CPU总核心数. worker_processe ...

  3. python2与python3爬虫中get与post对比

    python2中的urllib2改为python3中的urllib.request 四种方式对比: python2的get: # coding=utf-8 import urllib import u ...

  4. oracle管理索引

    索引是用于加速数据存取的数据对象,合理的使用索引可以大大降低I/O次数,从而提高数据访问性能.索引有很多种我们主要介绍常用的几种: 为什么添加了索引或,会加快查询速度呢? n  单列索引 单列索引是基 ...

  5. kendo grid 使用小结

    需要注意的: 1. id,如果没有指定id则会导致create.update等操作无法正常使用. 头疼事项: 1. 服务端失败返回error数据.如果是编辑状态,还不能友好提示错误.当然可以使用大量代 ...

  6. 反射技术的入口 获取类的Class信息

    package com.sxt.reflect; import com.sxt.reflect.entity.Student; /* * 获取类的Class信息 */ public class Tes ...

  7. 15-8 pymysql的使用

    一 安装pymysql模块 1 pycharm安装 file-setting如图:然后点加号,搜索pymsql即可,点击安装 2 pip 安装 pip3 install pymysql 二  连接数据 ...

  8. Android Joda-time工具类

    Joda-Time提供了一组Java类包用于处理包括ISO8601标准在内的date和time.可以利用它把JDK Date和Calendar类完全替换掉,而且仍然能够提供很好的集成.   Joda- ...

  9. Transformer的PyTorch实现

    Google 2017年的论文 Attention is all you need 阐释了什么叫做大道至简!该论文提出了Transformer模型,完全基于Attention mechanism,抛弃 ...

  10. oracle WHERE子句中的连接顺序

    ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾. 例如: (低效,执行时间1 ...