《Linux内核完全注释》学习笔记:2.3 Linux系统定时

在Linux 0.11内核中,PC的可编程定时芯片Intel 8253被设置成每隔10ms就发出一个时钟中断(IRQ0)信号。

这个时间节拍就是系统运行的脉搏,我们称之为1个系统滴答

因此每经过1个滴答就会调用一次时钟中断处理程序(timer_interrupt)

该处理程序主要用来通过 jiffies 变量来累计自系统启动以来经过的时钟滴答数。每当发生一次时钟中断该值就增1。然后从被中断程序的段选择符中取得当前特权级 CPL 作为参数调用 do_timer() 函数。

do_timer() 函数根据特权级对当前进程运行时间做累计。

  1. 如果 CPL=0,则表示进程是运行在内核态时被中断,因此把进程的内核运行时间统计值 stime 增1,否则把进程用户态运行时间统计值增1。

  2. 如果程序添加过定时器,则对定时器链表进行处理。

    • 若某个定时器时间到(递减后等于 0 ),则调用该定时器的处理函数。
  3. 然后对当前进程运行时间进行处理,把当前进程运行时间片减1。

    1. 如果此时当前进程时间片还大于 0 ,表示其时间片还没有用完,于是就退出 do_timer() 继续运行当前进程。
    2. 如果此时进程时间片已经递减为 0 ,表示该进程已经用完了此次使用CPU的时间片,于是程序就会根据被中断程序的级别来确定进一步处理的方法。
      1. 若被中断的当前进程是工作在用户态的(特权级别大于 0 ),则 do_timer() 就会调用调度程序 schedule() 切换到其他进程去运行。
      2. 如果被中断的当前进程工作在内核态,即在内核程序中运行时被中断,则 do_timer() 会立刻退出。

因此这样的处理方式决定了Linux系统在内核态运行时不会被调度程序切换
进程在内核态程序中运行时是不可抢占的,但当处于用户态程序中运行时则是可以被抢占的。

posted @   Larcvz  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示