日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux平台下 延迟工作队列实例

發(fā)布時間:2025/7/25 linux 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux平台下 延迟工作队列实例 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

? ? ? ? 工作隊(duì)列(work queue)是Linux內(nèi)核中將操作延期執(zhí)行的一種機(jī)制。因?yàn)樗鼈兪峭ㄟ^守護(hù)進(jìn)程在用戶上下文執(zhí)行,函數(shù)可以睡眠的時間,與內(nèi)核是無關(guān)的。在內(nèi)核版本2.5開發(fā)期間,設(shè)計(jì)了工作隊(duì)列,用以替換此前的keventd機(jī)制。

? ? ? ??這種機(jī)制和BH或Tasklets不同之處在于工作隊(duì)列是把延期的工作交由一個內(nèi)核線程去執(zhí)行,因此工作隊(duì)列的優(yōu)勢就在于它允許重新調(diào)度甚至睡眠。

? ? ? ??每個工作隊(duì)列多有一個數(shù)組,數(shù)據(jù)元素的數(shù)目與內(nèi)核處理器core的數(shù)目相同,每個數(shù)據(jù)元素都列出來將要延期執(zhí)行的任務(wù)。

? ? ? ??對于每個工作隊(duì)列來說,內(nèi)核都會創(chuàng)建一個新的內(nèi)核守護(hù)線程,延期任務(wù)使用上下文描述的等待隊(duì)列機(jī)制,在守護(hù)進(jìn)程的上下午執(zhí)行。

先定義幾個內(nèi)核中使用工作隊(duì)列時用到的術(shù)語方便后面描述。

  • workqueues:所有工作項(xiàng)被 ( 需要被執(zhí)行的工作 ) 排列于該隊(duì)列,因此稱作工作隊(duì)列 (workqueues) 。
  • worker thread:工作者線程 (worker thread) 是一個用于執(zhí)行工作隊(duì)列中各個工作項(xiàng)的內(nèi)核線程,當(dāng)工作隊(duì)列中沒有工作項(xiàng)時,該線程將變?yōu)?idle 狀態(tài)。
  • single threaded(ST)::工作者線程的表現(xiàn)形式之一,在系統(tǒng)范圍內(nèi),只有一個工作者線程為工作隊(duì)列服務(wù)
  • multi threaded(MT):工作者線程的表現(xiàn)形式之一,在多 CPU 系統(tǒng)上每個 CPU 上都有一個工作者線程為工作隊(duì)列服務(wù)

如何使用工作隊(duì)列哪?按如下步驟:

一.?????? 聲明一個工作隊(duì)列

staticstruct workqueue_struct *test_wq;

二.?????? 聲明一個延期工作描述實(shí)例

static struct delayed_work test_dwq;

三.?????? 聲明并實(shí)現(xiàn)一個工作隊(duì)列延遲處理函數(shù)

voiddelay_func(struct work_struct *work);

voiddelay_func(struct work_struct *work)

{

??? printk(KERN_INFO "My name isdelay_func!\n");

}

四.?????? 初始化一個工作隊(duì)列

test_wq = create_workqueue("test_wq");

五.?????? 任務(wù)初始化

INIT_DELAYED_WORK(&test_dwq,delay_func);

六. ? ? ? 向工作隊(duì)列提交工作項(xiàng)

queue_delayed_work(test_wq, &test_dwq, delay);

七. ? ? ? 取消工作隊(duì)列中的工作項(xiàng)

int cancel_delayed_work(test_wq);

? ? ? ?如果這個工作項(xiàng)在它開始執(zhí)行前被取消,返回值是非零。內(nèi)核保證給定工作項(xiàng)的執(zhí)行不會在調(diào)用 cancel_delay_work 成功后被執(zhí)行。 如果 cancel_delay_work 返回 0,則這個工作項(xiàng)可能已經(jīng)運(yùn)行在一個不同的處理器,并且仍然可能在調(diào)用 cancel_delayed_work 之后被執(zhí)行。要絕對確保工作函數(shù)沒有在 cancel_delayed_work 返回 0 后在任何地方運(yùn)行,你必須跟隨這個調(diào)用之后接著調(diào)用 flush_workqueue。在 flush_workqueue 返回后。任何在改調(diào)用之前提交的工作函數(shù)都不會在系統(tǒng)任何地方運(yùn)行。

八.?????? 刷新工作隊(duì)列

flush_workqueue(test_wq);


九.?????? 工作隊(duì)列銷毀

destroy_workqueue(test_wq);

?

涉及到的主要函數(shù)與結(jié)構(gòu)體

一.?????? 函數(shù)queue_delayed_work()

函數(shù)queue_delayed_work()是用于向工作隊(duì)列提交delayed_work實(shí)例,確保在延期執(zhí)行之前,至少會經(jīng)過由delay指定的一段時間(以jiffies為單位)。

該函數(shù)首先創(chuàng)建一個由內(nèi)核定時器,該定時器將在delayed jiffies之內(nèi)超時。

二.?????? 延期工作描述實(shí)例

structdelayed_work {

?????? struct work_struct work; /* 將作為實(shí)例被queue_work或queue_work_delayed添加到一個工作隊(duì)列*/

?????? struct timer_list timer; /* 延遲時間*/

};

三.?????? alloc_workqueue函數(shù)

struct workqueue_struct *alloc_workqueue(char *name, unsigned intflags, int max_active);

name:為工作隊(duì)列的名字,而不像 2.6.36 之前實(shí)際是為工作隊(duì)列服務(wù)的內(nèi)核線程的名字。

Flag: 指明工作隊(duì)列的屬性,可以設(shè)定的標(biāo)記如下:

  • WQ_NON_REENTRANT:默認(rèn)情況下,工作隊(duì)列只是確保在同一 CPU 上不可重入,即工作項(xiàng)不能在同一 CPU 上被多個工作者線程并發(fā)執(zhí)行,但容許在多個 CPU 上并發(fā)執(zhí)行。但該標(biāo)志標(biāo)明在多個 CPU 上也是不可重入的,工作項(xiàng)將在一個不可重入工作隊(duì)列中排隊(duì),并確保至多在一個系統(tǒng)范圍內(nèi)的工作者線程被執(zhí)行。
  • WQ_UNBOUND:工作項(xiàng)被放入一個由特定 gcwq 服務(wù)的未限定工作隊(duì)列,該客戶工作者線程沒有被限定到特定的 CPU,這樣,未限定工作者隊(duì)列就像簡單的執(zhí)行上下文一般,沒有并發(fā)管理。未限定的 gcwq 試圖盡可能快的執(zhí)行工作項(xiàng)。
  • WQ_FREEZEABLE:可凍結(jié) wq 參與系統(tǒng)的暫停操作。該工作隊(duì)列的工作項(xiàng)將被暫停,除非被喚醒,否者沒有新的工作項(xiàng)被執(zhí)行。
  • WQ_MEM_RECLAIM:所有的工作隊(duì)列可能在內(nèi)存回收路徑上被使用。使用該標(biāo)志則保證至少有一個執(zhí)行上下文而不管在任何內(nèi)存壓力之下。
  • WQ_HIGHPRI:高優(yōu)先級的工作項(xiàng)將被排練在隊(duì)列頭上,并且執(zhí)行時不考慮并發(fā)級別;換句話說,只要資源可用,高優(yōu)先級的工作項(xiàng)將盡可能快的執(zhí)行。高優(yōu)先工作項(xiàng)之間依據(jù)提交的順序被執(zhí)行。

·?????????WQ_CPU_INTENSIVE:CPU 密集的工作項(xiàng)對并發(fā)級別并無貢獻(xiàn),換句話說,可運(yùn)行的 CPU密集型工作項(xiàng)將不阻止其它工作項(xiàng)。這對于限定得工作項(xiàng)非常有用,因?yàn)樗谕嗟?CPU 時鐘周期,所以將它們的執(zhí)行調(diào)度交給系統(tǒng)調(diào)度器。

·?????????WQ_DRAINING:internal: workqueue is draining

·?????????WQ_RESCUER :internal: workqueue has rescuer

·?????????WQ_MAX_ACTIVE: I like 512, better ideas?

·?????????WQ_MAX_UNBOUND_PER_CPU: 4 * #cpus for unbound wq

·?????????WQ_DFL_ACTIVE:等于WQ_MAX_ACTIVE / 2,

max_active:決定了一個 wq 在 per-CPU 上能執(zhí)行的最大工作項(xiàng)。比如 max_active 設(shè)置為 16 表示一個工作隊(duì)列上最多 16 個工作項(xiàng)能同時在 per-CPU 上同時執(zhí)行。當(dāng)前實(shí)行中,對所有限定工作隊(duì)列,max_active 的最大值是 512,而設(shè)定為 0 時表示是 256;而對于未限定工作隊(duì)列,該最大值為:MAX[512,4 * num_possible_cpus() ],除非有特別的理由需要限流或者其它原因,一般設(shè)定為 0 就可以了

實(shí)例

/*********************************************** Author: lewiyon@hotmail.com* File name: delay_wq.c* Description: learn delay workqueue* Date: 2011-12-21*********************************************/#include <linux/kernel.h> #include <linux/module.h> #include <linux/proc_fs.h> #include <linux/workqueue.h> #include <linux/sched.h> #include <linux/init.h> #include <linux/interrupt.h>static struct workqueue_struct *test_wq; static struct delayed_work test_dwq;void delay_func(struct work_struct *work);void delay_func(struct work_struct *work) {printk(KERN_INFO "My name is delay_func!\n"); }static int __init example_init(void) {test_wq = create_workqueue("test_wq");if (!test_wq) {printk(KERN_ERR "No memory for workqueue\n");return 1; }printk(KERN_INFO "Create Workqueue successful!\n");INIT_DELAYED_WORK(&test_dwq, delay_func);queue_delayed_work(test_wq, &test_dwq, 0);return 0; }static void __exit example_exit(void) {destroy_workqueue(test_wq);printk(KERN_INFO "Goodbay!\n"); }module_init(example_init); module_exit(example_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("lewiyon <lewiyon@hotmail.com>");

轉(zhuǎn)載于:https://www.cnblogs.com/youngerchina/archive/2011/12/23/5624642.html

總結(jié)

以上是生活随笔為你收集整理的linux平台下 延迟工作队列实例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。