可见,创建的内核线程是执行工作队列中的所有函数。
除了最重要的创建函数,内核提供了一系列函数对其操作和方便编程,在这里介绍一个插入队列的函数。
/** * queue_work - queue work on a workqueue * @wq: workqueue to use * @work: work to queue * * Returns 0 if @work was already on a queue, non-zero otherwise. * * We queue the work to the CPU on which it was submitted, but if the CPU dies * it can be processed by another CPU. */ int queue_work(struct workqueue_struct *wq, struct work_struct *work) { int ret;
ret = queue_work_on(get_cpu(), wq, work); put_cpu();
return ret; } |
/** * queue_work_on - queue work on specific cpu * @cpu: CPU number to execute work on * @wq: workqueue to use * @work: work to queue * * Returns 0 if @work was already on a queue, non-zero otherwise. * * We queue the work to a specific CPU, the caller must ensure it * can't go away. */ int queue_work_on(int cpu, struct workqueue_struct *wq, struct work_struct *work) { int ret = 0;
if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) { BUG_ON(!list_empty(&work->entry)); __queue_work(wq_per_cpu(wq, cpu), work); ret = 1; } return ret; } |
最终调用insert_work函数
static void insert_work(struct cpu_workqueue_struct *cwq, struct work_struct *work, struct list_head *head) { trace_workqueue_insertion(cwq->thread, work);
set_wq_data(work, cwq); /* * Ensure that we get the right work->data if we see the * result of list_add() below, see try_to_grab_pending(). */ smp_wmb(); list_add_tail(&work->entry, head); wake_up(&cwq->more_work); } |
可见,在队列插入的时候就实现了唤醒。其他的函数不一一说了,了解了他的实现原理,看懂不难。