工作队列
(work queue)
是
Linux kernel
中将工作推后执行的一种机制。这种机制和
BH
或
Tasklets
不同之处在于工作队列是把推后的工作交由一个内核线程去执行,因此工作队列的优势就在于它允许重新调度甚至睡眠。
一、用到得函数如下:
INIT_WORK(_work, _func, _data);
int schedule_work(struct work_struct *work);
int schedule_delayed_work(struct work_struct *work, unsigned long delay);
void flush_scheduled_work(void);
int cancel_delayed_work(struct work_struct *work);
1、
初始化指定工作,目的是把用户指定的函数
_func
及
_func
需要的参数
_data
赋给
work_struct
的
func
及
data
变量。
2、对工作进行调度,即把给定工作的处理函数提交给缺省的工作队列和工作者线程。工作者线程本质上是一个普通的内核线程,在默认情况下,每个CPU均有一个类型为“events”的工作者线程,当调用schedule_work时,这个工作者线程会被唤醒去执行工作链表上的所有工作。
3、延迟执行工作,与schedule_work类似。
4、刷新缺省工作队列。此函数会一直等待,直到队列中的所有工作都被执行。
5、flush_scheduled_work并不取消任何延迟执行的工作,因此,如果要取消延迟工作,应该调用cancel_delayed_work。
以上均是采用缺省工作者线程来实现工作队列,其优点是简单易用,缺点是如果缺省工作队列负载太重,执行效率会很低,这就需要我们创建自己的工作者线程和工作队列。struct workqueue_struct *create_workqueue(const char *name);
int queue_work(struct workqueue_struct *wq, struct work_struct *work);
int queue_delayed_work(struct workqueue_struct *wq, struct work_struct *work, unsigned long delay);
void flush_workqueue(struct workqueue_struct *wq);
void destroy_workqueue(struct workqueue_struct *wq);
1、
创建新的工作队列和相应的工作者线程,
name
用于该内核线程的命名。
2、类似于schedule_work,区别在于queue_work把给定工作提交给创建的工作队列wq而不是缺省队列。
3、延迟执行工作。
4、刷新指定工作队列。
5、释放创建的工作队列。
二、实例代码如下:
void my_func(void *data)
{
char *name = (char *)data;
printk(KERN_INFO “Hello world, my name is %s!\n”, name);
}
struct workqueue_struct *my_wq = create_workqueue(“my wq”);
struct work_struct my_work;
INIT_WORK(&my_work, my_func, “Jack”);
queue_work(my_wq, &my_work);
destroy_workqueue(my_wq);