14.3 Linux 中断处理的核心:顶半部和底半部
中国有句俗话:鱼与熊掌不可兼得。这句话也充分体现在了中断处理上。在一定的时间内完成的工作量和工作的复杂程度往往是对立的。也就是说,如果想在1小时内做很多工作,那么每项工作就不能太复杂,否则不可能完成任务。中断处理也是一样。内核在处理中断请求时要求在单位时间内处理尽可能多的中断,也就是说要求处理中断的吞吐率要尽可能地大。这就要求中断处理函数中的代码尽可能地短小,而且不能有耗时的操作。但这往往很不现实。事实上,大多数中断处理程序是很复杂的,也不是在很短的时间就可以执行完的。为了解决这个问题,内核设计者将中断处理分为两个阶段,也就是我们常说的顶半部(Top Half)和底半部(Bottom Half)。通过顶半部和底半部,可以在某种程度上缓解鱼与熊掌不可兼得的问题。
处理中断可以分为如下两部分。
接收和响应中断请求。
处理中断的业务逻辑。
一般复杂的工作都在处理中断的业务逻辑中。而接收和响应中断请求会在很短的时间被处理完。根据这两项工作所需的时间差异,很容易想到可以同步来执行中断请求的接收和响应,而通过异步的方式执行耗时比较多的操作,也就是处理中断的业务逻辑。
我们在编写服务端网络程序时往往会开启一个监听线程来接收客户端的请求。一旦接收到某个客户端的请求,一般不会直接在监听线程中处理客户端的请求,而是再开启一个专门处理客户端请求的线程,并在该线程中处理客户端的请求。这样监听线程就可以解脱出来处理更多的客户端请求,从而大大提高服务端程序的吞吐量。
中断处理程序和服务端网络程序类似,当硬件向内核发送中断请求时,内核(在这里内核就相当于服务端网络程序)首先会接收中断请求,这个接收中断请求的任务就是由中断处理程序的顶半部完成的。然而在顶半部中并不会执行中断处理的核心代码,而这些代码需要在底半部完成。对于顶半部来说,除了接收中断请求外,还会进行"登记工作"。也就是说要将底半部处理程序挂到发送中断请求的设备的底半部执行队列中。这样的安排,顶半部的执行速度就会很快,可以服务更多的中断请求。
现在,中断处理工作的重心已经落在了底半部的头上,由底半部来完成中断处理的大部分工作。底半部几乎做了中断处理程序所有的事情,而且可以被新的中断打断,这也是底半部和顶半部的***不同,因为顶半部不能被其他中断打断。底半部则相对来说并不是非常紧急的,而且相对比较耗时,并且不在硬件中断服务程序中执行。
尽管中断处理可以通过顶半部和底半部的结合来改善系统的响应能力,但是在实际的应用中并不一定要分两个半部来处理。如果处理中断的任务很小,耗时比较短,完全可以直接在顶半部完成,根本就不需要底半部的参与。
【责任编辑:book TEL:(010)68476606】
点赞 0