tasklet和workqueue区别

一、中断处理的tasklet(小任务)机制

  中断服务程序一般都是在中断请求关闭的条件下执行的,以避免嵌套而使中断控制复杂化。但是,中断时一个随机事件,它随时会到来,如果管中断的事件太长,cpu就不能及时响应其他的中断请求,从而造成中断的丢失,因此,linux内核的母庙就是尽可能快的处理完中断请求,尽可能快的处理完中断请求,尽其所能把更多的处理向后推迟。假如一个数据块已经到达了网线,当中断控制器接受到这个中断请求信号时,linux内核只是简单地标志数据到来了,然后让处理器恢复到它以前运行的状态,其余的处理稍后再进行(如把数据移入一个缓冲区,接受数据的进程就可以在缓冲区找到数据)。因此,内核把中断处理分为两部分:上半部(tophalf)和下半部(bottomhalf),上半部(就是中断服务程)内核立即执行,而下半部(就是一些内核函数)留着稍后处理。 首先,一个快速的"上半部"来处理硬件发出的请求,它必须在一个新的中断产生之前终止,通常,除了在设备和一些内存缓冲区(如果你的设备用到DMA,就不指这些)之间移动或传送数据,确当硬件是否处于健全的状态之外,这一部分做的工作很少,下半部运行时是允许中断请求的,而上半部运行时是关中断的。 这是二者之间的主要区别。

  二、中断处理的工作队列机制

  tasklet 

     小任务不能休眠,因此不能在小任务中使用信号量或者其他产生阻塞的函数,但是小人物运行时可以响应中断。

    调度自己的小任务通过调用tasklet_schedule()函数并传递给它想应的tasklet_struct指针,该小任务就会被调度一边适当的时候执行。

    小任务被调度以后,只要有机会他就会尽可能早的运行。在它还没有得到运行机会之前那,如果一个相同的小任务又被调用了,那么它仍然指挥运行一次。

    可以调用tasklet_disable()函数来禁止某个指定的小人物,如果该小任务当前正在执行,这个函数会等到它执行完毕再返回。

    也可以调用tasklet_kill() 函数从挂起的队列中去掉一个小任务,该函数的参数四一个指向某个小任务的tasklet_struct的长指针。在小任务重新调度它自身的时候,从挂起的队列中移去已调度的小任务会很有用,这个函数首先等待该小任务执行完毕,然后再将它移去。

    推迟的事情由tasklet_handler实现,何时执行 ,经由小人物机制封装后交给内核去处理

  

 

  工作队列(work queue)是另外一种将工作推后执行的形式,它和前面讨论的tasklet有所不同, 工作队列可以把工作推后,交由一个内核线程去执行,也就是说,这个下半部分可以在进程上下文中执行,这样,通过工作队执行的代买能占进程上下文的所有优势。最重要的就是工作对垒允许被重新调度甚至是睡眠

  这意味这在获取大量的内存时,在需要获取信号量时,在需要执行阻塞式的I/O操作时,它都会非常有用,

  

上一篇:linux内核设计与实现总结(3-10章)


下一篇:《linux kernel develpoment》第八章