当前位置 主页 > 服务器问题 > Linux/apache问题 > 最大化 缩小

    Linux之时钟中断详解

    栏目:Linux/apache问题 时间:2019-10-11 10:13

    在Linux的0号中断是一个定时器中断。在固定的时间间隔都发生一次中断,也是说每秒发生该中断的频率都是固定的。该频率是常量HZ,该值一般是在100 ~ 1000之间。该中断的作用是为了定时更新系统日期和时间,使系统时间不断地得到跳转。另外该中断的中断处理函数除了更新系统时间外,还需要更新本地CPU统计数。指的是调用scheduler_tick递减进程的时间片,若进程的时间片递减到0,进程则被调度出去而放弃CPU使用权。

    时钟中断的产生

    Linux的OS时钟的物理产生原因是可编程定时/计数器产生的输出脉冲,这个脉冲送入CPU,就可以引发一个中断请求信号,我们就把它叫做时钟中断。

    “时钟中断”是特别重要的一个中断,因为整个操作系统的活动都受到它的激励。系统利用时钟中断维持系统时间、促使环境的切换,以保证所有进程共享CPU;利用时钟中断进行记帐、监督系统工作以及确定未来的调度优先级等工作。可以说,“时钟中断”是整个操作系统的脉搏。

    时钟中断的物理产生如图所示:

    操作系统对可编程定时/计数器进行有关初始化,然后定时/计数器就对输入脉冲进行计数(分频),产生的三个输出脉冲Out0、Out1、Out2各有用途,很多接口书都介绍了这个问题,我们只看Out0上的输出脉冲,这个脉冲信号接到中断控制器8259A_1的0号管脚,触发一个周期性的中断,我们就把这个中断叫做时钟中断,时钟中断的周期,也就是脉冲信号的周期,我们叫做“滴答”或“时标”(tick)。从本质上说,时钟中断只是一个周期性的信号,完全是硬件行为,该信号触发CPU去执行一个中断服务程序,但是为了方便,我们就把这个服务程序叫做时钟中断。

    Linux实现时钟中断的全过程

    1.可编程定时/计数器的初始化

    IBM PC中使用的是8253或8254芯片。有关该芯片的详细知识我们不再详述,只大体介绍以下它的组成和作用,如下表5.1所示:

    表 8253/8254的组成及作用

    名称

    端口地址

    工作方式

    产生的输出脉冲的用途

    计数器0

    0x40

    方式3

    时钟中断,也叫系统时钟

    计数器1

    0x41

    方式2

    动态存储器刷新

    计数器2

    0x42

    方式3

    扬声器发声

    控制寄存器

    0x43

    /

    用于8253的初始化,接收控制字

    计数器0的输出就是图中的Out0,它的频率由操作系统的设计者确定,Linux对8253的初始化程序段如下(在/arch/i386/kernel/i8259.c的init_IRQ()函数中):

    set_intr_gate(ox20, interrupt[0]); 
     
    /*在IDT的第0x20个表项中插入一个中断门。这个门中的段选择符设置成内核代码段的选择符,偏移域设置成0号中断处理程序的入口地址。*/ 
     
    outb_p(0x34,0x43);  /* 写计数器0的控制字:工作方式2*/ 
     
    outb_p(LATCH & 0xff , 0x40); /* 写计数初值LSB 计数初值低位字节*/ 
     
    outb(LATCH >> 8 , 0x40); /* 写计数初值MSB 计数初值高位字节*/ 
     
    LATCH(英文意思为:锁存器,即其中锁存了计数器0的初值)为计数器0的计数初值,在/include/linux/timex.h中定义如下: 
     
    #define CLOCK_TICK_RATE 1193180 /* 图5.3中的输入脉冲 */ 
     
    #define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* 计数器0的计数初值 */