Linux 核心--12.Linux内核机制( 二 )


immediate
immediate 底层处理过程的优先级低于定时器底层处理过程,所以此类型任务将延迟运行 。
scheduler
此任务队列直接由调度管理器来处理 。它被用来支撑系统中其他任务队列,此时可以运行的任务是一个处理任务队列的过程,如设备驱动 。
当处理任务队列时,处于队列头部的元素将从队列中删除同时以空指针代替它 。这个删除操作是一个不可中断的原子操作 。队列中每个元素的处理过程将被依次调用 。这个队列中的元素通常使用静态分配数据 。然而并没有一个固有机制来丢弃已分配内存 。任务队列处理例程简单的指向链表中下一个元素 。这个任务才真正清除任何已分配的核心内存 。


11.3定时器(TIMER)



图11.3 系统定时器


操作系统应该能够在将来某个时刻准时调度某个任务 。所以需要一种能保证任务较准时调度运行的机制 。希望支持每种操作系统的微处理器必须包含一个可周期性中断它的可编程间隔定时器 。这个周期性中断被称为系统时钟滴答,它象节拍器一样来组织系统任务 。

Linux的时钟观念很简单:它表示系统启动后的以时钟滴答记数的时间 。所有的系统时钟都基于这种量度,在 系统中的名称和一个全局变量相同-jiffies 。

Linux包含两种类型的系统定时器,它们都可以在某个系统时间上被队列例程使用,但是它们的实现稍有区别 。图11.3画出了这两种机制 。

第一个是老的定时器机制,它包含指向timer_struct结构的32位指针的静态数组以及当前活动定时器的屏蔽码 :time_active 。

此定时器表中的位置是静态定义的(类似底层部分处理表bh_base) 。其入口在系统初始化时被加入到表中 。第二种是相对较新的定时器,它使用一个到期时间以升序排列的timer_list结构链表 。

这两种方法都使用jiffies作为终结时间,这样希望运行5秒的定时器将不得不将5秒时间转换成jiffies 的单位并且将它和以jiffies记数的当前系统时间相加从而得到定时器的终结时间 。在每个系统时钟滴答时,定时器的底层部分处理过程被标记成活动状态以便调度管理器下次运行时能进行定时器队列的处理 。定时器底层 部分处理过程包含两种类型的系统定时器 。老的系统定时器将检查timer_active位是否置位 。

如果活动定时器已经到期则其定时器例程将被调用同时它的活动位也被清除 。新定时器位于timer_list结构链表中的入口也将受到检查 。每个过期定时器将从链表中清除,同时它的例程将被调用 。新定时器机制的优点之一是能传递一个参数给定时器例程 。




11.4等待队列
进程经常要等待某个系统资源 。例如某个进程可能需要描叙文件系统中某个目录的VFS inode但是此inode可 能不在buffer cache中 。此时这个进程必须等到该inode从包含此文件系统的物理介质中取出来才可以继续 运行 。



wait_queue
*task

*next
图11.4 等待队列


Linux核心使用一个非常简单的队列:等待队列(见图11.4) 。它包含一个指向进程task_struct结构的指针以及等待队列中下一个元素的指针 。加入到等待队列中的进程既可以是可中断也可以是不可中断的 。可中断 进程能够被如定时器到期或者信号等时间中断 。此等待进程的状态必须说明成是INTERRUPTIBLE还是 UNINTERRUPTIBLE 。由于进程现在不能继续运行则调度管理器将接过系统控制权并选择一个新进程运行而等待进程将被挂起 。处理等待进程时,每个处于等待队列中的进程都被置为RUNNING状态 。如果此进程已经从运行队列中删除则它将被重新放入运行队列 。下次调度管理器运行时, 由于这些进程不再等待所以它们都将是运行候选者 。等待队列可以用来同步对系统资源的访问, 同时它们还被Linux用于信号灯的实现中 。

推荐阅读