工作佇列分析

2021-06-05 10:01:04 字數 3011 閱讀 1537

一、用法

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;

}

工作佇列分析

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

工作佇列分析 queue work

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

工作佇列分析 queue work

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