Linux2.6中斷下半部分的三種實現機制---工作隊列

Linux 2.6內核使用了不少工作隊列來處理任務,他在使用上和 tasklet最大的不同是工作隊列的函數可以使用休眠,而tasklet的函數是不允許使用休眠的。
工作隊列的使用又分兩種情況,一種是利用系統共享的工作隊列來增加自己的工作,這種情況處理函數不能消耗過多時間,這樣會影響共享隊列中其他任務的處理;別的一種是創建自己的工作隊列並添加工作。


(一)利用系統共享的工作隊列添加工作:
第一步:聲明或編寫一個工作處理函數
void my_func();


第二步:創建一個工作結構體變量,並將處理函數和參數的入口地址賦給這個工作結構體變量
DECLARE_WORK(my_work,my_func,&data); //編譯時創建名爲my_work的結構體變量並把函數入口地址和參數地址賦給它;


假如不想要在編譯時創建,就用DECLARE_WORK()創建並初始化工作結構體變量,也可以在程序運行時再用INIT_WORK()創建
struct work_struct my_work; //創建一個名爲my_work的結構體變量,創建後才能使用INIT_WORK()
INIT_WORK(&my_work,my_func,&data); //初始化已經創建的my_work,其實便是往這個結構體變量中添加處理函數的入口地址和data的地址,通常在驅動的open函數中完成


第三步:將工作結構體變量添加入系統的共享工作隊列
schedule_work(&my_work); //添加入隊列的工作完成後會自動從隊列中刪除

schedule_delayed_work(&my_work,tick); //延時tick個滴答後再提交工作


(二)創建自己的工作隊列來添加工作
第一步:聲明工作處理函數和一個指向工作隊列的指針
void my_func();
struct workqueue_struct *p_queue;


第二步:創建自己的工作隊列和工作結構體變量(通常在open函數中完成)
p_queue=create_workqueue("my_queue"); //創建一個名爲my_queue的工作隊列並把工作隊列的入口地址賦給聲明的指針


struct work_struct my_work;
INIT_WORK(&my_workmy_func,&data); //創建一個工作結構體變量並初始化,和第一種情況的辦法一樣


第三步:將工作添加入自己創建的工作隊列等待執行
queue_work(p_queue,my_work);
//作用與schedule_work()相似,不同的是將工作添加入p_queue指針指向的工作隊列而不是系統共享的工作隊列


第四步:刪除自己的工作隊列
destroy_workqueue(p_queue); //基本是在close函數中刪除

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章