作者:云天明
链接:https://www.zhihu.com/question/50764115/answer/122613742
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

cpu里面有可编程间隔定时器(PIT,Programmable interval timer),目前x86-64/arm/8051-based的绝大多数cpu/mcu都是内置PIT的,PIT以一个可调节的时间间隔触发时钟中断,使得操作系统的时钟中断处理程序可以可调节地周期性运行。时钟中断处理程序负责维护所有的软件定时器,在当前进程的时间片用光,或有定时器触发时执行进程调度(线程调度),并维护软件时钟。

PIT和RTC的区别:计算机中有一枚纽扣电池负责在关机时维持CMOS数据并驱动一个低频时钟,这个时钟叫做实时钟(Real-time clock),注意RTC是相当不精确的,所以大多数操作系统通常在开机之后维护一个软件时钟,通过时钟中断和网咯时间协议(http://www.ntp.org/)维护的软件时钟比RTC精确和可靠得多,绝大多数操作系统除了开机时会读取RTC,关机时将RTC与软件时钟同步以外,大多数时间RTC都是孤独地运行的。

PIT与WDT的区别:有些嵌入式MCU除了提供PIT以外还提供看门狗定时器(Watchdog timer),有些PIT可以用于WDT功能,有些WDT具有PIT功能,有些场合PIT和WDT可能使用相同的时钟源,但两者是不同的。PIT用于周期性产生中断信号,而WDT一旦触发,产生的是复位信号,嵌入式操作系统需要不停地重置WDT以阻止复位信号的产生,WDT主要用于从软件错误中自动恢复。

嗯,实名反对另外…………不是咱不懂别强答好么←_←

以上是硬件部分

当一个线程执行了sleep(1000)时,首先会陷入到内核态执行系统调用处理程序,相关的处理程序会设置一个软件定时器(1000),然后转向线程调度,这时候会进行线程上下文切换和进程上下文切换,线程调度程序将该线程标记为等待态,并标记该线程等待该定时器的信号,然后执行线程调度。

当时钟中断处理程序发现这个软件定时器触发时,便将这个信号量置位(或者复位?),然后通知线程调度模块,线程调度发现这个信号量与某个线程相关联,于是将线程标记为就绪态,这时候
{当前线程的优先级更高:继续执行当前进程,
当前进程是idle/当前线程优先级低:转向执行刚进入就绪态的线程并标记为当前线程,切换进程上下文,恢复保存的线程现场,然后把触发的定时器和信号量参数传递给线程的内核态部分(系统调用处理程序),系统调用处理程序删除定时器然后返回到用户态}

sleep存在误差的原因在于,你交出控制权以后,定时的时间到了你还能不能被分到时间片是未知数,所以有可能定时器时间到了线程并没有马上进入执行态,但是这个在pc上不是个事,服务器才需要考虑这个

不过linux内核有个奇葩的东西叫做高解析度定时模式,和另外一个奇葩的东西叫做完全无滴答模式,在高解析度定时模式下,linux通过对PIT编程使得定时尽量精确(PIT的触发周期是可调的,最低我记得小于微秒级,和CPU有关),这样使得软件定时器可以精确到微秒级,有时候在高精度定时模式下linux的时钟中断是完全没有周期性的,每触发一次时钟中断就要改一次定时周期。完全无滴答模式是把PIT直接关掉的,当然如果你有定时需求系统会把这玩意再打开。

linux 时间模块 一的更多相关文章

  1. linux 时间模块 三

    LINUX的时钟中断中涉及至二个全局变量一个是xtime,另一个则是jiffies.有一个与时间有关的时钟:实时时钟(RTC),这是一个硬件时钟,用来持久存放系统时间,系统关闭后靠主板上的微型电池保持 ...

  2. linux 时间模块 二

    Linux中有硬件时钟与系统时钟 在Linux中有硬件时钟与系统时钟等两种时钟.硬件时钟是指主机板上的时钟设备,也就是通常可在BIOS画面设定的时钟.系统时钟则是指kernel中的时钟.当Linux启 ...

  3. s14 第5天 时间模块 随机模块 String模块 shutil模块(文件操作) 文件压缩(zipfile和tarfile)shelve模块 XML模块 ConfigParser配置文件操作模块 hashlib散列模块 Subprocess模块(调用shell) logging模块 正则表达式模块 r字符串和转译

    时间模块 time datatime time.clock(2.7) time.process_time(3.3) 测量处理器运算时间,不包括sleep时间 time.altzone 返回与UTC时间 ...

  4. Linux时间子系统之(二):软件架构

    专题文档汇总目录 Notes:从框架上讲解了时间子系统,从底向上包括CPU Local TImer.Global Counter.Clock Souce/Clock Events模块管理.Tick D ...

  5. Linux时间子系统之(三):用户空间接口函数

    专题文档汇总目录 Notes:用户空间时间相关接口函数: 类型 API 精度 说明 时间 time stime time_t 精度为秒级 逐渐要被淘汰.需要定义__ARCH_WANT_SYS_TIME ...

  6. Linux时间子系统之(四):timekeeping

    专题文档汇总目录 Notes:timekeeping模块的狠心数据结构是timekeeper,它维护了系统不同类型时钟的时间值,并且介绍了获取不同类型时钟时间的函数. clocksource切换通过c ...

  7. Linux时间子系统之(五):POSIX Clock

    专题文档汇总目录 Notes: 本章主要介绍了若干种类的静态时钟,这些时钟都可以通过k_clock表示,注册到posix_clocks中.这些都是静态时钟,可以分为三大类:各种REALTIME时钟.带 ...

  8. Linux时间子系统之(十三):Tick Device layer综述

    专题文档汇总目录 Notes:从概念层次描述了tick-comm.oneshot tick.broadcast tick:重点介绍了tick和tickless概念及其区别,两种tick device: ...

  9. Linux时间子系统之(十四):tick broadcast framework

    专题文档汇总目录 Notes:BroadcastTick作为cpuidle的waker,硬件基础.BroadcastTick嵌入在当前系统Tick框架中.BroadcastTick设备初始化:周期性T ...

随机推荐

  1. iOS应用架构谈-part2 view层的组织和调用方案

    前言 <iOS应用架构谈 开篇>出来之后,很多人来催我赶紧出第二篇.这一篇文章出得相当艰难,因为公司里的破事儿特别多,我自己又有点私事儿,以至于能用来写博客的时间不够充分. 现在好啦,第二 ...

  2. Vue实例和生命周期

    创建一个Vue实例 每个Vue应用都是通过Vue函数创建一个新的Vue实例开始: var vm = new Vue({ //选项 }) 数据与方法 当一个Vue实例被创建时,它向Vue的响应式系统中加 ...

  3. 优酷项目之 ORM(数据库对象关系映射)代码重写

    前言: 我们在操作数据库时候一般都是通过sql代码来操作mysql数据库中相关数据,这就需要懂得sql语句,那么怎么样才能在不懂sql语句的情况下通过我们所学的python代码来实现对mysql数据库 ...

  4. 2018 Python开发者大调查:Python和JavaScript最配?

    在2018年秋季,Python软件基金会与JetBrains发起了年度Python开发者调查. 报告的目的是寻找Python领域的新趋势,帮助开发者深入了解2018年Python开发者的现状. 该报告 ...

  5. ACM-ICPC 2015 Shenyang Preliminary Contest B. Best Solver

    The so-called best problem solver can easily solve this problem, with his/her childhood sweetheart. ...

  6. 【转】git bash here 右键菜单失效后的修复方法

    [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shell\git_shell] @="Git Ba&sh Here"   [ ...

  7. Andorid 生成NDK动态链接库 .so库

    .so库第一次见到是在搜索Android保存静态秘钥等特殊id字段做法时看到的-通过NDK的方式将静态秘钥保存在so文件中, 关于原生开发工具包(NDK)详细见官网指南要更详细,这里我记录我度娘各种结 ...

  8. PostgreSQL order by 排序问题

    默认的排序为order by 字段名, 如果该字段不允许为空的情况下可以这样操作, 但是当字段允许为null时,order by 字段名的方式会导致: 升序时(asc): 会从最小值开始升序,最后面接 ...

  9. C#发送邮件异常,返回信息乱码

    发邮件时出现了异常: 在 System.Net.Mail.MailCommand.CheckResponse(SmtpStatusCode statusCode, String response) 在 ...

  10. Welcome-to-Swift-15反初始化(Deinitialization)

    在一个类的实例被释放之前,反初始化函数被立即调用.用关键字deinit来标示反初始化函数,类似于初始化函数用init来标示.反初始化函数只适用于类类型. 反初始化原理 Swift会自动释放不再需要的实 ...