分类: LINUX
2012-12-14 16:53:20
工作队列(work queue):具有延时执行的特点。
一、数据结构:
struct work_struct {
unsigned long pending;
struct list_head entry;
void (*func)(void *);
void *data;
void *wq_data;
struct timer_list timer;
};
pending是用来记录工作是否已经挂在队列上;
entry是循环链表结构;
func作为函数指针,由用户实现;用来指定处理函数的。
data用来存储用户的私人数据,此数据即是func的参数;
wq_data一般用来指向工作者线程(工作者线程参考下文);
timer是推后执行的定时器。
work_struct的这些变量里,func和data是用户使用的,其他是内部变量,我们可以不用太过关心
二、API:
1) INIT_WORK(_work, _func, _data)
初始化指定工作,目的是把用户指定的函数_func(处理函数)及_func需要的参数_data赋给work_struct的func及data变量。
2) int schedule_work(struct work_struct *work)
对工作进行调度,即把给定工作的处理函数提交给缺省的工作队列和工作者线程。工作者线程本质上是一个普通的内核线程,在默认情况下,每个CPU均有一个类型为“events”的工作者线程,当调用schedule_work时,这个工作者线程会被唤醒去执行工作链表上的所有工作。在内部定时器的时间到了后执行。
3) int schedule_delayed_work(struct work_struct *work, unsigned long delay)
延迟执行工作,与schedule_work类似。
4) void flush_scheduled_work(void)
刷新缺省工作队列。此函数会一直等待,直到队列中的所有工作都被执行。
5) int cancel_delayed_work(struct work_struct *work)
flush_scheduled_work并不取消任何延迟执行的工作,因此,如果要取消延迟工作,应该调用cancel_delayed_work。
三、代码
static irqreturn_t mma7660_irq(int irq, void *handle)
{
struct mma7660 *gs = handle;
/* The repeated conversion sequencer controlled by TMR kicked off too fast.
* We ignore the last and process the sample sequence currently in the queue.
* It can't be older than 9.4ms
*/
SEP0611_INT_DISABLE(SEP0611_GSENSOR_INTSRC);
sep0611_gpio_clrirq(SEP0611_GSENSOR_INT);
if (!work_pending(&gs->work))
schedule_work(&gs->work);
SEP0611_INT_ENABLE(SEP0611_GSENSOR_INTSRC);
return IRQ_HANDLED;
}
此函数为一个中断处理函数:if语句是判断工作队列是否已在任务队列中,若不在则通过schedule_work(&gs->work);
调度添加队列,此工作队列的处理函数并不立即执行,而是被加入任务队列中等待执行。终端服务程序通过schedule_work(&gs->work)调度工作队列后,并不等待其处理完毕,而是继续往下执行,并返回,工队队列处理函数等到工作队列内部时钟到时后才回去执行。