一、用法
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...