在Linux 0.11内核中,PC的可编程定时芯片Intel 8253被设置成每隔10ms就发出一个时钟中断(IRQ0)信号。
这个时间节拍就是系统运行的脉搏,我们称之为1个系统滴答。
因此每经过1个滴答就会调用一次时钟中断处理程序(timer_interrupt)。
该处理程序主要用来通过
jiffies
变量来累计自系统启动以来经过的时钟滴答数。每当发生一次时钟中断该值就增1。然后从被中断程序的段选择符中取得当前特权级 CPL 作为参数调用do_timer()
函数。
do_timer()
函数根据特权级对当前进程运行时间做累计。
-
如果 CPL=0,则表示进程是运行在内核态时被中断,因此把进程的内核运行时间统计值
stime
增1,否则把进程用户态运行时间统计值增1。 -
如果程序添加过定时器,则对定时器链表进行处理。
- 若某个定时器时间到(递减后等于 0 ),则调用该定时器的处理函数。
-
然后对当前进程运行时间进行处理,把当前进程运行时间片减1。
- 如果此时当前进程时间片还大于 0 ,表示其时间片还没有用完,于是就退出
do_timer()
继续运行当前进程。 - 如果此时进程时间片已经递减为 0 ,表示该进程已经用完了此次使用CPU的时间片,于是程序就会根据被中断程序的级别来确定进一步处理的方法。
- 若被中断的当前进程是工作在用户态的(特权级别大于 0 ),则
do_timer()
就会调用调度程序schedule()
切换到其他进程去运行。 - 如果被中断的当前进程工作在内核态,即在内核程序中运行时被中断,则
do_timer()
会立刻退出。
- 若被中断的当前进程是工作在用户态的(特权级别大于 0 ),则
- 如果此时当前进程时间片还大于 0 ,表示其时间片还没有用完,于是就退出
标签:中断,timer,进程,内核,Linux,2.3,运行 From: https://www.cnblogs.com/Larcvz/p/18196719因此这样的处理方式决定了Linux系统在内核态运行时不会被调度程序切换。
进程在内核态程序中运行时是不可抢占的,但当处于用户态程序中运行时则是可以被抢占的。