转自 http://b8807053.pixnet.net/blog/post/292002646-%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8queue_delayed_work%E5%87%BD%E6%95%B8
1. delayed_workqueue主要用在需要延遲處理任務的驅動中,這些驅動的特性主要是不能使用中斷。
delayed_workqueue的使用步驟如下:
1) 定義workqueue要做的delayed工作:struct delayed_work mdelayed_work;
2) 定義workqueue: struct workqueue_struct *mworkqueue;
3) 初始化workqueue:INIT_DELAYED_WORK(mworkqueue, mdelayed_work);
4) 創建執行緒queue並加以名字:mworkqueue = create_singlethread_workqueue("myqueue");
5) 運行queue:queue_delayed_work(mworkqueue, mdelayed_work, delay_time);
注:如果要實現迴圈實行任務,可以在在delayed_work中將delayed_workqueue再次添加到queue中,即在delayed_work中調用queue_delayed_work。
2.舉例分析:
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/workqueue.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
struct delayed_work mdwq;
struct workqueue_struct *mwq;
void delay_work_func(struct work_struct *work)
{
int i;
for (i = 0; i < 3; i++) {
printk(KERN_ERR "%s:i=%d\n",__FUNCTION__,i);
msleep(3000);
}
}
static int __init delay_work_init(void)
{
int ret;
int i;
mwq = create_workqueue("my workqueue");
if (!mwq) {
printk(KERN_ERR "Create workqueue failed!\n");
return 1;
}
printk(KERN_INFO "Create workqueue successful!\n");
INIT_DELAYED_WORK(&mdwq, delay_work_func);
ret = queue_delayed_work(mwq, &mdwq, 3000);
printk(KERN_INFO "first ret=%d!\n", ret);
for (i = 0; i < 3; i++) {
printk(KERN_INFO "%s:ret=%d,i=%d\n",__FUNCTION__,ret, i);
msleep(1000);
}
ret = queue_delayed_work(mwq, &mdwq, 0);
printk(KERN_INFO "second ret=%d!\n", ret);
return 0;
}
static void __exit delay_work_exit(void)
{
int ret;
ret = cancel_delayed_work(&mdwq);
flush_workqueue(mwq);
destroy_workqueue(mwq);
}
module_init(delay_work_init);
module_exit(delay_work_exit);
MODULE_LICENSE("GPL");
運行結果:
kernel: Create workqueue successful!
kernel: first ret=1!
kernel: delay_work_init:ret=1,i=0
kernel: delay_work_init:ret=1,i=1
kernel: delay_work_init:ret=1,i=2
kernel: second ret=0!
kernel: Exit! ret=1
從例子可以看出當工作隊列還在執行該任務,調用queue_delayed_work()返回1,否則返回0。
主執行緒mwq將任務添加到工作隊列後,使得工作隊列在延遲delay後執行函數delay_work_func(),而mwq執行緒繼續執行;