Linux 工作佇列

2021-05-25 04:53:57 字數 2449 閱讀 8547

工作佇列(

work queue) 是另外一種將工作推後執行的形式,它和tasklet有所不同。工作佇列可以把工作推後,交由乙個核心執行緒去執行,也就是說,這個下半部分可以 在程序上下文中執行。這樣,通過工作佇列執行的**能佔盡程序上下文的所有優勢。最重要的就是工作佇列允許被重新排程甚至是睡眠。

那麼,什麼情況下使用工作佇列,什麼情況下使用 tasklet 。如果推後執行的任務需要睡眠,那麼就選擇工作佇列。如果推後執行的任務不需要睡眠,那麼就選擇 tasklet 。另外,如果需要用乙個可以重新排程的實體來執行你的下半部處理,也應該使用工作佇列。它是唯一能在程序上下文執行的下半部實現的機制,也只有它才可以睡眠。這意味著在需要獲得大量的記憶體時、在需要獲取訊號量時,在需要執行阻塞式的 i/o 操作時,它都會非常有用。如果不需要用乙個核心執行緒來推後執行工作,那麼就考慮使用 tasklet 。

工作、工作佇列和工作者執行緒

如前所述,我們把推後執行的任務叫做工作( work ),描述它的資料結構為 work_struct ,這些工作以佇列結構組織成工作佇列( workqueue ),其資料結構為 workqueue_struct ,而工作執行緒就是負責執行工作佇列中的工作。系統預設的工作者執行緒為 events, 自己也可以建立自己的工作者執行緒。

表示工作的資料結構

工作用 中定義的 work_struct 結構表示:

struct work_struct;

這些結構被連線成鍊錶。當乙個工作者執行緒被喚醒時,它會執行它的鍊錶上的所有工作。工作被執行完畢,它就將相應的 work_struct 物件從鍊錶上移去。當鍊表上不再有物件的時候,它就會繼續休眠。

3. 建立推後的工作

要使用工作佇列,首先要做的是建立一些需要推後完成的工作。可以通過 declare_work 在編譯時靜態地建該結構:

declare_work(name, void (*func) (void *), void *data);

這樣就會靜態地建立乙個名為 name ,待執行函式為 func ,引數為 data 的 work_struct 結構。

同樣,也可以在執行時通過指標建立乙個工作:

init_work(struct work_struct *work, woid(*func) (void *), void *data);

這會動態地初始化乙個由 work 指向的工作。

4. 工作佇列中待執行的函式

工作佇列待執行的函式原型是:

void work_handler(void *data)

這 個函式會由乙個工作者執行緒執行,因此,函式會執行在程序上下文中。預設情況下,允許響應中斷,並且不持有任何鎖。如果需要,函式可以睡眠。需要注意的是, 儘管該函式執行在程序上下文中,但它不能訪問使用者空間,因為核心執行緒在使用者空間沒有相關的記憶體對映。通常在系統呼叫發生時,核心會代表使用者空間的程序運 行,此時它才能訪問使用者空間,也只有在此時它才會對映使用者空間的記憶體。

5. 對工作進行排程

現在工作已經被建立,我們可以排程它了。想要把給定工作的待處理函式提交給預設的 events 工作執行緒,只需呼叫

schedule_work(&work) ;

work 馬上就會被排程,一旦其所在的處理器上的工作者執行緒被喚醒,它就會被執行。

有時候並不希望工作馬上就被執行,而是希望它經過一段延遲以後再執行。在這種情況下,可以排程它在指定的時間執行:

schedule_delayed_work(&work, delay);

這時, &work 指向的 work_struct 直到 delay 指定的時鐘節拍用完以後才會執行。

6. 工作佇列的簡單應用 #

include

<

linux

/module.h

>

#include

<

linux

/init.h

>

#include

<

linux

/workqueue.h

>

static

struct

workqueue_struct

*queue

=null

;static

struct

work_struct work

;static

void

work_handler

(struct

work_struct

*data

)static

int__init test_init

(void

)static

void

__exit test_exit

(void

)module_license

("gpl"

);module_init

(test_init

);module_exit

(test_exit);

linux工作佇列

在linux核心中,對下半部 或者說推後執行的工作 的處理方式有好幾種,包括bh bottom half 軟中斷,tasklets和工作佇列等等。在2.6核心中,大名鼎鼎的bh處理被廢除,新增了更方便的工作佇列。工作佇列的方便之處在於它把工作推後,交由乙個核心執行緒去執行,這個核心執行緒總會在程序上...

linux工作佇列

linux工作佇列 1.功能描述 工作佇列 work queue 是linux kernel中將工作推後執行的一種機制。這種機制和bh或tasklets不同之處在於工作佇列是把推後的工作交由乙個核心執行緒去執行,因此工作佇列的優勢就在於它允許重新排程甚至睡眠。2.工作佇列結構體 typedef vo...

linux 工作佇列 補充

走入linux的殿堂已經有一年有餘了,在這裡我想將linux的各種實現機制分析一遍,一方面對自己來說也是溫故而知新,另一方面,促進大家的交流,最好能夠給大家一些拋磚引玉的啟迪。我是硬體出身,搞硬體已經好多年了,從是專門軟體開發也接近兩年了,在這一段時間內我越發認為軟硬體協同設計是未來發展的主流,軟硬...