首页 / 操作系统 / Linux / Linux操作系统内核中工作队列的操作
本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性,严禁用于任何商业用途。 msn: yfydz_no1@hotmail.com 来源:http://yfydz.cublog.cn 1. 前言 工作队列(workqueue)的Linux内核中的定义的用来处理不是很紧急事件的回调方式处理方法. 以下代码的linux内核版本为2.6.19.2, 源代码文件主要为kernel/workqueue.c. 2. 数据结构 /* include/linux/workqueue.h */ // 工作节点结构 struct work_struct { // 等待时间 unsigned long pending; // 链表节点 struct list_head entry; // workqueue回调函数 void (*func)(void *); // 回调函数func的数据 void *data; // 指向CPU相关数据, 一般指向struct cpu_workqueue_struct结构 void *wq_data; // 定时器 struct timer_list timer; }; struct execute_work { struct work_struct work; }; /* kernel/workqueue.c */ /* * The per-CPU workqueue (if single thread, we always use the first * possible cpu). * * The sequence counters are for flush_scheduled_work(). It wants to wait * until all currently-scheduled works are completed, but it doesn"t * want to be livelocked by new, incoming ones. So it waits until * remove_sequence is >= the insert_sequence which pertained when * flush_scheduled_work() was called. */ // 这个结构是针对每个CPU的 struct cpu_workqueue_struct { // 结构锁 spinlock_t lock; // 下一个要执行的节点序号 long remove_sequence; /* Least-recently added (next to run) */ // 下一个要插入节点的序号 long insert_sequence; /* Next to add */ // 工作机构链表节点 struct list_head worklist; // 要进行处理的等待队列 wait_queue_head_t more_work; // 处理完的等待队列 wait_queue_head_t work_done; // 工作队列节点 struct workqueue_struct *wq; // 进程指针 struct task_struct *thread; int run_depth; /* Detect run_workqueue() recursion depth */ } ____cacheline_aligned; /* * The externally visible workqueue abstraction is an array of * per-CPU workqueues: */ // 工作队列结构 struct workqueue_struct { struct cpu_workqueue_struct *cpu_wq; const char *name; struct list_head list; /* Empty if single thread */ }; kernel/workqueue.c中定义了一个工作队列链表, 所有工作队列可以挂接到这个链表中: static LIST_HEAD(workqueues); 3. 一些宏定义 /* include/linux/workqueue.h */ // 初始化工作队列 #define __WORK_INITIALIZER(n, f, d) { // 初始化list .entry = { &(n).entry, &(n).entry }, // 回调函数 .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 a work-struct"s func and data pointers: */ // 重新定义工作结构参数 #define PREPARE_WORK(_work, _func, _data) do { (_work)->func = _func; (_work)->data = _data; } while (0) /* * initialize all of a work-struct: */ // 初始化工作结构, 和__WORK_INITIALIZER功能相同,不过__WORK_INITIALIZER用在 // 参数初始化定义, 而该宏用在程序之中对工作结构赋值 #define INIT_WORK(_work, _func, _data) do { INIT_LIST_HEAD(&(_work)->entry); (_work)->pending = 0; PREPARE_WORK((_work), (_func), (_data)); init_timer(&(_work)->timer); } while (0) 4. 操作函数 4.1 创建工作队列 一般的创建函数是create_workqueue, 但这其实只是一个宏: /* include/linux/workqueue.h */ #define create_workqueue(name) __create_workqueue((name), 0)