linux INIT_WORK 创建工作队列
一.利用系统共享的工作队列添加工作
1.声明或编写一个工作处理函数
void my_func();
2.创建一个工作结构体变量,并将处理函数和参数的入口地址赋给这个工作结构体变量
DECLARE_WORK(my_work,my_func,&data); ->编译时创建名为my_work的结构体变量并把函数入口地址和参数地址赋给它;
如果不想要在编译时就用DECLARE_WORK()创建并初始化工作结构体变量,也可以在程序运行时再用INIT_WORK()创建:
struct work_struct my_work; ->创建一个名为my_work的结构体变量,创建后才能使用INIT_WORK()
INIT_WORK(&my_work,my_func,&data); ->初始化已经创建的my_work,其实就是往这个结构体变量中添加处理函数的入口地址和data的地址,通常在驱动的open函数中完成
3.将工作结构体变量添加入系统的共享工作队列
schedule_work(&my_work); ->添加入队列的工作完成后会自动从队列中删除
二.创建自己的工作队列来添加工作
1.声明工作处理函数和一个指向工作队列的指针
void my_func();
struct workqueue_struct *p_queue;
2.创建自己的工作队列和工作结构体变量(通常在open函数中完成)
p_queue=create_workqueue(“my_queue”); ->创建一个名为my_queue的工作队列并把工作队列的入口地址赋给声明的指针
struct work_struct my_work;
INIT_WORK(&my_work, my_func, &data);
3.将工作添加入自己创建的工作队列等待执行
queue_work(p_queue, &my_work); ->作用与schedule_work()类似,不同的是将工作添加入p_queue指针指向的工作队列而不是系统共享的工作队列
4.删除自己的工作队列
destroy_workqueue(p_queue); ->一般是在close函数中删除
关于工作队列方面问题的理解(个人理解)
首先,工作队列是一个单线程,所作出的事件,对于系统的其他部分来说并没有重大的影响。
程序中添加的工作队列是系统共享工作队列,这个工作队列的使用方法如下(以验证失败的AQUA项目中的LED闪烁模式作为例子)
1.单独编写一个工作处理函数:
static void gpio_led_flash_work(struct work_struct *work)
2.在程序总数据结构中创建一个工作结构体变量
struct work_struct flash_work;
3.初始化一个创建的工作体变量:
INIT_WORK(&led_dat->flash_work, gpio_led_flash_work);
4.在需要调用到工作处理函数的地方,将工作结构体变量添加到系统的共享工作队列:
schedule_work(&led_dat->flash_work);