Linux下的中断按照中断源的不同可以分为硬件中断和软中断,下面就两者的区别和联系做下简单比较:
硬件中断:
中断点:
由硬件向当前CPU发起中断,请求CPU资源。当CPU执行完当前指令后,检查到有中断请求需要响应,进而关闭中断,调用由用户事先注册好的中断处理程序(ISR)。如果被中断的进程位于用户空间,还要发生堆栈的切换,将堆栈切换到进程的内核堆栈。当然,在中断处理程序用指令IRET返回的时候,堆栈还要切换到中断前的状态。
中断嵌套和并行:
不同优先级的中断之间可能出现嵌套,在多CPU系统上可能出现并行。对于由同一个中断源引起的中断,他们之间出现的是假的嵌套,实际上他们之间还是串行的,即使是在多CPU系统上。并且他们最多嵌套两层(包括开始的那个中断),多于两个的中断,将被丢弃。当然,是否允许中断的嵌套和并行,还是在我们的掌控之中的,为了简化中断服务程序设计,我们可以选择禁止任何形式的嵌套和并行。
其它:
有些书上不建议在开中断的条件下执行中断处理程序,并解释说这是为了防止中断嵌套导致程序设计的复杂性增加,实则不然,因为同一个中断服务程序的多个实例之间还是串行执行的。与其关掉中断,不合理占用CPU资源,不如打开中断。当然,即使是打开中断,我们的中断处理程序也不应该肆意加长,还应以简单为好。如果实在有很多操作要作,请考虑采用软中断的形式缓冲硬中断,就和网络数据包的接收一样。
注意:
在开中断的条件下执行中断处理程序,本级的中断可能被低优先级的中断中断,造成中断优先级反转。虽然同一中断源的中断之间是串行的,但是不同中断源之间是可以嵌套和并行的,如果有变量需要在多个中断源的处理程序之间共享,最好还是关闭本地中断,且对数据用自旋锁进行保护,防止由多处理器所造成的不一致。
软中断:
中断点:
当系统在硬中断处理程序,或者其它的处理程序中需要触发某个软中断处理程序时,就设置相应的软中断标志位。当系统从硬件中断最终返回到非中断上下文时将检查是否有软件中断需要相应,如果有,则调用其软中断处理函数。当然,也可以手动调用软中断处理函数进入软中断,例如netif_rx_ni函数,不过需要特别小心。另外,软中断并不一定运行于中断上下文(可以理解为未从IRET返回的部分),如果,系统的软中断比较频繁,为了保证系统的响应,在几次软中断之后,将启用软中断的内核守护线程,由他处理后续的软中断,进而给其它进程以被调度运行的机会。
嵌套和并行:
软中断在同一个CPU上是顺序执行的,不允许嵌套和并行,执行的顺序按照软中断的优先级(参看以前的文章)。注意:这种优先级不是说高优先级的软中断可以中断低优先级的软中断,而是说在一个处理循环中,如果同时有多个软中断处于就绪状态,那么高优先级的软中断将先于低优先级的软中断被执行。
但是,在多CPU的系统上,软中断是可以并行执行的,所以写程序的时候需要特别注意共享的变量需要用自旋锁保护。