Linux驅動中delayed_workqueue使用:
在驅動中,有時不能使用中斷(這種情況很少遇到), 此時delayed_workqueue就可以發揮其巨大的功效了。也可以用其它同類的核心API實現:如timer。
delayed_workqueue的使用過程如下:
--> 定義workqueue: struct workqueue_struct *test_workqueue; // 定義在: kernel/workqueue.c
--> 定義workqueue要做的delayed工作:struct delayed_work test_delayed_work; // 定義在: include/linux/workqueue.h
--> 初始化workqueue:INIT_DELAYED_WORK(test_delayed_work, test_workqueue_func); // 定義在:include/linux/workqueue.h
--> 建立線程queue並加以名字:test_workqueue = create_singlethread_workqueue("name_of_this_queue");
--> 運行queue:queue_delayed_work(test_workqueue, test_delayed_work, delay_time); // 定義在:kernel/workqueue.c, 其中delay_time是延遲多少時間來運行queue。
註: 在test_workqueu_func中一定要再次將delayed_workqueue加入queue中,即再次運行queue_delayed_work。否則,此queue只運行一次。
下面詳細講解每個函數。
#define INIT_DELAYED_WORK(_work, _func)\do {\INIT_WORK(&(_work)->work, (_func));\init_timer(&(_work)->timer);\} while (0)
#define INIT_WORK(_work, _func)\do {\(_work)->data = (atomic_long_t) WORK_DATA_INIT();\INIT_LIST_HEAD(&(_work)->entry);\PREPARE_WORK((_work), (_func));\} while (0)#endif// WORK_DATA_INIT() == 0;// PREPARE_WORK((_work), (_func)) == (_work)->func = (_func);struct delayed_work {struct work_struct work;struct timer_list timer;};
INIT_WORK的主要工作是data賦值為0;
初始化entry鏈表;
將_func傳給work的_func。
#define init_timer(timer) init_timer_key((timer), NULL, NULL)
init_timer_key((timer), NULL, NULL) --> debug_time_init [ NOP]
使用delayed workqueue最主要的是調用queue_delayed_work。
如果delay = 0,則直接調用:queue_work
其具體實現過程:queue_work --> queue_work_on --> __queue_work --> insert_work
如果delay !=0,則調用:queue_delayed_work_on
其具體實現過程:queue_delayed_work_on 此函數是通過timer來完成最後的延時工作。