工作佇列分析 queue work

2021-06-04 23:24:11 字數 3067 閱讀 3112

一、用法 

struct cpu_workqueue_struct  ____cacheline_aligned; 

/* * the externally visible workqueue abstraction is an array of 

* per-cpu workqueues: 

*/ struct workqueue_struct ; 

工作佇列的使用很簡單。 

1.首先是建立乙個工作佇列: 

struct workqueue_struct *keventd_wq; 

keventd_wq = create_workqueue("events"); 

2.然後就是在這個佇列中insert你所要做的「工作」: 

declare_work(work, func, data)

queue_work(keventd_wq, work); 

struct work_struct ; 

初始化有兩種方法。 

一種為靜態方法: 

#define __work_initializer(n, f, d) , \ 

.func = (f), \ 

.data = (d), \ 

.timer = timer_initializer(null, 0, 0), \ 

} #define declare_work(n, f, d) \ 

struct work_struct n = __work_initializer(n, f, d) 

另一種為動態方法: 

/* * initialize all of a work-struct: 

*/ #define init_work(_work, _func, _data) \ 

do  while (0) 

二、執行過程 

create_workqueue() -> __create_workqueue() 

struct workqueue_struct *__create_workqueue(const char *name, 

int singlethread) 

else  else 

destroy = 1; 

} } 

mutex_unlock(&workqueue_mutex); 

... 

return wq; 

} create_workqueue() -> __create_workqueue() -> create_workqueue_thread() 

static struct task_struct *create_workqueue_thread(struct workqueue_struct *wq, 

int cpu) 

create_workqueue() -> __create_workqueue() -> create_workqueue_thread() -> worker_thread() 

//本函式在乙個死迴圈等待工作的到來,這一般在睡眠狀態中,等待被喚醒執行工作 

//當有工作到來時queue_work()會將這個執行緒喚醒 

static int worker_thread(void *__cwq) 

__set_current_state(task_running); 

return 0; 

} create_workqueue() -> __create_workqueue() -> create_workqueue_thread()  

-> worker_thread() -> run_workqueue() 

//該函式執行真正的工作 

static void run_workqueue(struct cpu_workqueue_struct *cwq) 

cwq->run_depth--; 

spin_unlock_irqrestore(&cwq->lock, flags); 

} 三、工作執行緒建立的詳細過程 

create_workqueue() -> __create_workqueue() -> create_workqueue_thread()  

-> kthread_create() 

struct task_struct *kthread_create(int (*threadfn)(void *data), 

void *data, 

const char namefmt, 

...) 

... 

return create.result; 

} create_workqueue() -> __create_workqueue() -> create_workqueue_thread()  

-> kthread_create()-> keventd_create_kthread() 

//最終會呼叫kernel_thread為每個工作佇列建立乙個執行緒 

//這樣,被建立的執行緒會以create為資料執行kthread(如下),而kthread中則執行create中的threadfn(data), 

//即為create_workqueue_thread中的worker_thread(cwq),即為我們工作佇列要執行的函式了。 

static void keventd_create_kthread(void *_create) 

else  

complete(&create->done); 

} static int kthread(void *_create) 

四、插入「工作」 

/* preempt must be disabled. */ 

static void __queue_work(struct cpu_workqueue_struct *cwq, 

struct work_struct *work) 

int fastcall queue_work(struct workqueue_struct *wq, struct work_struct *work) 

put_cpu(); 

return ret; 

}

工作佇列分析 queue work

一 用法 struct cpu workqueue struct cacheline aligned the externally visible workqueue abstraction is an array of per cpu workqueues struct workqueue str...

工作佇列分析

一 用法 struct cpu workqueue struct cacheline aligned the externally visible workqueue abstraction is an array of per cpu workqueues struct workqueue str...

工作佇列分析

一 用法 struct cpu workqueue struct cacheline aligned the externally visible workqueue abstraction is an array of per cpu workqueues struct workqueue str...