linux内核知识之工作队列(workqueue)

    工作队列(work queue)Linux kernel中将工作推后执行的一种机制。这种机制和BHTasklets不同之处在于工作队列是把推后的工作交由一个内核线程去执行,因此工作队列的优势就在于它允许重新调度甚至睡眠

    数据结构:

struct work_struct {
	atomic_long_t data;
#define WORK_STRUCT_PENDING 0		/* T if work item pending execution */
#define WORK_STRUCT_STATIC  1		/* static initializer (debugobjects) */
#define WORK_STRUCT_FLAG_MASK (3UL)
#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)
	struct list_head entry;
	work_func_t func;
#ifdef CONFIG_LOCKDEP
	struct lockdep_map lockdep_map;
#endif
};

func作为函数指针,由用户实现;

data用户的私人数据,通过container_of来得到用户数据

work_struct的这些变量里,funcdata是用户使用的,其他是内部变量,我们可以不用太过关心。


API

1) INIT_WORK(_work, _func)/INIT_DELAYED_WORK(_work,_func)

初始化指定工作,目的是把用户指定的函数_func赋给work_structfunc

2) int schedule_work(struct work_struct *work)------>> queue_work

对工作进行调度,即给定工作的处理函数提交给缺省的工作队列和工作者线程。工作者线程本质上是一个普通的内核线程,在默认情况下,每个CPU均有一个类型为“events”的工作者线程,当调用schedule_work时,这个工作者线程会被唤醒去执行工作链表上的所有工作。

3) int schedule_delayed_work(struct work_struct *work, unsigned long delay) ---> queue_delayed_work --> queue_work

延迟执行工作,与schedule_work类似。

4) void flush_scheduled_work(void)

刷新缺省工作队列。此函数会一直等待,直到队列中的所有工作都被执行。

5) int cancel_delayed_work(struct work_struct *work)
   flush_scheduled_work并不取消任何延迟执行的工作,因此,如果要取消延迟工作,应该调用cancel_delayed_work

以上均是采用缺省工作者线程来实现工作队列,其优点是简单易用,缺点是如果缺省工作队列负载太重,执行效率会很低这就需要我们创建自己的工作者线程和工作队列,这种情况我们暂不讨论。

为什么只要这里初始化好了,到时候调用schedule_delayed_work()就可以了呢?事实上,events这么一个线程吧,有事情就处理,没事情就睡眠,也是一个死循环,schedule_delayed_work()的作用就是唤醒这个线程,确切的说,是先把自己的这个struct work_struct插入workqueue_struct这个队列里,然后唤醒昏睡中的events.然后events就会去处理,您要是有延时,那么它就给您安排延时以后执行,您要是没有延时,或者您设了延时为0,那好,那就赶紧给您执行.咱这里不是讲了两个宏吗,一个INIT_WORK(),一个INIT_DELAYED_WORK(),后者就是专门用于可以有延时的,而前者就是没有延时的,这里咱们调用的是INIT_DELAYED_WORK()。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值