原文地址:schedule_delayed_work()用法
作者:Valley
第一篇 工作隊列
在Linux內核中,對下半部(或者說推后執行的工作)的處理方式有好幾種,包括BH(bottom
half),軟中斷,Tasklets和工作隊列等等。在2.6內核中,大名鼎鼎的BH處理被廢除,新增了更方便的工作隊列。工作隊列的方便之處在於它把 工作推后,交由一個內核線程去執行,這個內核線程總會在進程上下文執行,因此,它就可以很方便的持有信號量(semaphore),當然也可以允許睡眠。
內核對工作隊列的處理是通過工作者線程完成的。工作者線程在一般情況下處於睡眠狀態,當我們把需要推遲執行的工作注冊到工作隊列中之后,喚醒工作者線程會 遍歷工作隊列中的每個待處理的工作,並執行工作隊列結構work_struct中的func函數。這里涉及到兩個概念:工作者線程和工作隊列。首先看看我 們最關心的工作隊列。
struct work_struct *delayed_work;
INIT_WORK(delayed_work, delayed_work_handler, data);
schedule_work(delayed_work);
delayed_work是我們聲明的工作隊列;通過INIT_WORK對工作隊列進行初始化,delayed_work_handler是工作隊列的處 理函數,data是傳遞給處理函數的參數;最后調用schedule_work喚醒工作者線程處理推后執行的工作。如果需要經過一段延遲以后再執行工作, 可以調用:
schedule_delayed_work(delayed_work, delay); //delay 是需要延遲的節拍數
另外還有一種靜態創建工作隊列的方式:
DECLARE_WORK(name, void (*func) (void *), void *data);
大部分情況下我們了解到這里已經足夠了。工作者線程可以放心的交給內核去完成。對於工作者線程的使用有兩種方式,一是直接使用內核中每個CPU對應的一個 缺省工作者線程envents/n(n代表CPU的序號,從0開始);再者就是自己創建一個專用的工作者線程。對於通常情況下,驅動開發者是不必關心工作 者線程的,缺省的工作者線程能夠做的很好。如果缺省的隊列不能滿足要求,自己創建一個工作者線程也很簡單,只需要調用:
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);
它們與schedule_work()以及schedule_delayed_work()是類似的。
在Linux內核中,對下半部(或者說推后執行的工作)的處理方式有好幾種,包括BH(bottom
half),軟中斷,Tasklets和工作隊列等等。在2.6內核中,大名鼎鼎的BH處理被廢除,新增了更方便的工作隊列。工作隊列的方便之處在於它把 工作推后,交由一個內核線程去執行,這個內核線程總會在進程上下文執行,因此,它就可以很方便的持有信號量(semaphore),當然也可以允許睡眠。
內核對工作隊列的處理是通過工作者線程完成的。工作者線程在一般情況下處於睡眠狀態,當我們把需要推遲執行的工作注冊到工作隊列中之后,喚醒工作者線程會 遍歷工作隊列中的每個待處理的工作,並執行工作隊列結構work_struct中的func函數。這里涉及到兩個概念:工作者線程和工作隊列。首先看看我 們最關心的工作隊列。
struct work_struct *delayed_work;
INIT_WORK(delayed_work, delayed_work_handler, data);
schedule_work(delayed_work);
delayed_work是我們聲明的工作隊列;通過INIT_WORK對工作隊列進行初始化,delayed_work_handler是工作隊列的處 理函數,data是傳遞給處理函數的參數;最后調用schedule_work喚醒工作者線程處理推后執行的工作。如果需要經過一段延遲以后再執行工作, 可以調用:
schedule_delayed_work(delayed_work, delay); //delay 是需要延遲的節拍數
另外還有一種靜態創建工作隊列的方式:
DECLARE_WORK(name, void (*func) (void *), void *data);
大部分情況下我們了解到這里已經足夠了。工作者線程可以放心的交給內核去完成。對於工作者線程的使用有兩種方式,一是直接使用內核中每個CPU對應的一個 缺省工作者線程envents/n(n代表CPU的序號,從0開始);再者就是自己創建一個專用的工作者線程。對於通常情況下,驅動開發者是不必關心工作 者線程的,缺省的工作者線程能夠做的很好。如果缺省的隊列不能滿足要求,自己創建一個工作者線程也很簡單,只需要調用:
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);
它們與schedule_work()以及schedule_delayed_work()是類似的。