作者:云天明
链接: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直接关掉的,当然如果你有定时需求系统会把这玩意再打开。

最新文章

  1. h5自定义audio(问题及解决)
  2. C++中的内联成员函数与非内联成员函数
  3. 廖雪峰js教程笔记6 generator一个坑 看完python在回来填坑
  4. 看那记不住命令的猿,如何使用GitHub
  5. 转载大神的检测网站重定向的python脚本
  6. Ubuntu14.10 更新源,现在很多源已经停用了建议使用ubuntu15以上
  7. wordpress 提取头像的src
  8. PHP的抽象类和接口
  9. JAVA中常用需要设置的三个环境变量(JAVA_HOME、CLASSPATH、PATH)
  10. 闲聊之Python的数据类型 - 零基础入门学习Python005
  11. C++多态的实现原理
  12. HDFS追本溯源:HDFS操作的逻辑流程与源码解析
  13. idea在springboot项目中没有【新建JSP选项】的解决方法
  14. 解读经典《C#高级编程》第七版 Page20-32.核心C#.Chapter2
  15. python检查URL是否能正常访问
  16. loj6045 价
  17. json数据的处理和转化(loads/load/dump/dumps)
  18. Mac - 如何安全地还原 Mac 的默认字体
  19. Java实现窗体动态加载磁盘文件
  20. Leetcode 526

热门文章

  1. 【Ubuntu】ubuntu基本操作命令
  2. 【kindle】【转发】kindle链接WIFI自动断开问题
  3. 基于IAR6或者IAR7建立STM32开发工程(通过实际测试,使用IAR6.30.4)
  4. ZOJ 2314 (sgu 194) Reactor Cooling (无源汇有上下界最大流)
  5. 牛客网暑期ACM多校训练营(第七场)A Minimum Cost Perfect Matching(找规律)
  6. UVa 579 Clock Hands
  7. 《Scrum实战》第3次课【富有成效的每日站会】作业汇总
  8. Leetcode12--->Integer to Roman(整数转换为罗马数字)
  9. python - unittest - 单元测试
  10. TOJ 3581: 最简IPv6表示