普通队列
一、定义工作入口项
struct workqueue_struct *suspend_work_queue;
二、创建单线程的工作队列
suspend_work_queue = create_singlethread_workqueue("suspend");
if (suspend_work_queue == NULL) {
ret = -ENOMEM;
goto err_suspend_work_queue;//跳到err_suspend_work_queue不需要对workqueue有什么操作,因为队列没有创建成功,
/*如果创建成功,则可以使用
if (suspend_work_queue)
destroy_workqueue(suspend_work_queue);
来释放相关的资源
*/
}
三、声明和初始化工作队列入口项
static DECLARE_WORK(suspend_work, suspend);//suspend_work是声明的结构体名称;suspend是函数
四、实现处理函数
static void suspend(struct work_struct *work)
{
………………
}
五、将工作提交到工作队列
queue_work(suspend_work_queue, &suspend_work);//需要使用队列的时候,调用这个函数
六、不使用队列时,释放相关资源
destroy_workqueue(suspend_work_queue);//这个只在有创建队列的时候使用,共享队列不能和不必使用
延时队列
一、定义工作队列和工作入口项
static struct workqueue_struct *mdp_pipe_ctrl_wq; /* mdp mdp pipe ctrl wq */
static struct delayed_work mdp_pipe_ctrl_worker;
二、创建单线程的工作队列
mdp_pipe_ctrl_wq = create_singlethread_workqueue("mdp_pipe_ctrl_wq");
三、声明和初始化工作队列入口项
INIT_DELAYED_WORK(&mdp_pipe_ctrl_worker, mdp_pipe_ctrl_workqueue_handler);
//mdp_pipe_ctrl_worker是要声明的结构体名称,mdp_pipe_ctrl_workqueue_handler 是处理函数
四、实现处理函数
static void mdp_pipe_ctrl_workqueue_handler(struct work_struct *work)//处理函数
{
mdp_pipe_ctrl(MDP_MASTER_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
}
五、将工作提交到工作队列
queue_delayed_work(mdp_pipe_ctrl_wq, &mdp_pipe_ctrl_worker,mdp_timer_duration);//调用工作队列
六、删除队列
/* cancel pipe ctrl worker */
cancel_delayed_work(&mdp_pipe_ctrl_worker);//返回值为0则说明该入口项已经在其他处理器上运行,因此在cancel_delayed_work返回后可能仍在运行
//为了保证cancel_delayed_work在返回0之后,工作函数都不会在系统的任何地方运行,在应随后调用下面的函数
/* for workder can't be cancelled... */
flush_workqueue(mdp_pipe_ctrl_wq);
共享队列
(共享队列不应该长期独占改队列,即不能长时间睡眠,而且我们的任务可能需要更长得时间才能获得处理器)
一、定义工作入口项
static struct work_struct ssd2531_wq_updateEvn;
二、声明和初始化工作队列入口项
INIT_WORK(&ssd2531_wq_updateEvn, ssd2531_do_work_updateEvn);
三、实现处理函数
static void ssd2531_do_work_updateEvn(struct work_struct *work)
{
…………
}
四、在需要的地方调用
schedule_work(&ssd2531_wq_updateEvn);
共享延时队列
(其中DECLARE_WORK替代DECLARE_DELAYED_WORK,schedule_work替代schedule_delayed_work就可以变为非延时队列了)
一、声明处理函数
static void jack_func(struct work_struct *work);
二、声明和初始化工作队列入口项
DECLARE_DELAYED_WORK(jack_work,jack_func); //DECLARE_WORK(jack_work,jack_func);
三、在需要的地方调用
schedule_delayed_work(&jack_work,HZ); //schedule_work(&jack_work);
四、删除队列
cancel_delayed_work(&jack_work); //cancel_work_sync(&jack_work);//注意:没有cancel_work这个函数
初始化有两种方法。
一种为静态方法:
#define DECLARE_WORK(n, f) \
struct work_struct n = __WORK_INITIALIZER(n, f)
#define __WORK_INITIALIZER(n, f) { \
.data = WORK_DATA_INIT(), \
.entry = { &(n).entry, &(n).entry }, \
.func = (f), \
__WORK_INIT_LOCKDEP_MAP(#n, &(n)) \
}
另一种为动态方法:
#define INIT_WORK(_work, _func) \
do { \
(_work)->data = (atomic_long_t) WORK_DATA_INIT(); \
INIT_LIST_HEAD(&(_work)->entry); \
PREPARE_WORK((_work), (_func)); \
} while (0)
#endif
DECLARE_WORK和INIT_WORK可以互替,但是使用INIT_WORK时一定要先定义work_struct结构体,如
static struct work_struct ssd2531_wq_updateEvn;
INIT_WORK(&ssd2531_wq_updateEvn, ssd2531_do_work_updateEvn);
DECLARE_WORK(ssd2531_wq_updateEvn, ssd2531_do_work_updateEvn);
同理,DECLARE_DELAYED_WORK和INIT_DELAYED_WORK也可以互替
schedule_work和queue_work可以互替使用
create_workqueue 与 create_singlethread_workqueue 的区别
create_workqueue 内核会在系统中的每个处理器上为该工作队列创建专用的线程,在许多情况下,众多的线程可能会对性能具有某种程度的杀伤力,
因此如果单个工作线程足够使用,那么应该使用 create_singlethread_workqueue
一、定义工作入口项
struct workqueue_struct *suspend_work_queue;
二、创建单线程的工作队列
suspend_work_queue = create_singlethread_workqueue("suspend");
if (suspend_work_queue == NULL) {
ret = -ENOMEM;
goto err_suspend_work_queue;//跳到err_suspend_work_queue不需要对workqueue有什么操作,因为队列没有创建成功,
/*如果创建成功,则可以使用
if (suspend_work_queue)
destroy_workqueue(suspend_work_queue);
来释放相关的资源
*/
}
三、声明和初始化工作队列入口项
static DECLARE_WORK(suspend_work, suspend);//suspend_work是声明的结构体名称;suspend是函数
四、实现处理函数
static void suspend(struct work_struct *work)
{
………………
}
五、将工作提交到工作队列
queue_work(suspend_work_queue, &suspend_work);//需要使用队列的时候,调用这个函数
六、不使用队列时,释放相关资源
destroy_workqueue(suspend_work_queue);//这个只在有创建队列的时候使用,共享队列不能和不必使用
延时队列
一、定义工作队列和工作入口项
static struct workqueue_struct *mdp_pipe_ctrl_wq; /* mdp mdp pipe ctrl wq */
static struct delayed_work mdp_pipe_ctrl_worker;
二、创建单线程的工作队列
mdp_pipe_ctrl_wq = create_singlethread_workqueue("mdp_pipe_ctrl_wq");
三、声明和初始化工作队列入口项
INIT_DELAYED_WORK(&mdp_pipe_ctrl_worker, mdp_pipe_ctrl_workqueue_handler);
//mdp_pipe_ctrl_worker是要声明的结构体名称,mdp_pipe_ctrl_workqueue_handler 是处理函数
四、实现处理函数
static void mdp_pipe_ctrl_workqueue_handler(struct work_struct *work)//处理函数
{
mdp_pipe_ctrl(MDP_MASTER_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
}
五、将工作提交到工作队列
queue_delayed_work(mdp_pipe_ctrl_wq, &mdp_pipe_ctrl_worker,mdp_timer_duration);//调用工作队列
六、删除队列
/* cancel pipe ctrl worker */
cancel_delayed_work(&mdp_pipe_ctrl_worker);//返回值为0则说明该入口项已经在其他处理器上运行,因此在cancel_delayed_work返回后可能仍在运行
//为了保证cancel_delayed_work在返回0之后,工作函数都不会在系统的任何地方运行,在应随后调用下面的函数
/* for workder can't be cancelled... */
flush_workqueue(mdp_pipe_ctrl_wq);
共享队列
(共享队列不应该长期独占改队列,即不能长时间睡眠,而且我们的任务可能需要更长得时间才能获得处理器)
一、定义工作入口项
static struct work_struct ssd2531_wq_updateEvn;
二、声明和初始化工作队列入口项
INIT_WORK(&ssd2531_wq_updateEvn, ssd2531_do_work_updateEvn);
三、实现处理函数
static void ssd2531_do_work_updateEvn(struct work_struct *work)
{
…………
}
四、在需要的地方调用
schedule_work(&ssd2531_wq_updateEvn);
共享延时队列
(其中DECLARE_WORK替代DECLARE_DELAYED_WORK,schedule_work替代schedule_delayed_work就可以变为非延时队列了)
一、声明处理函数
static void jack_func(struct work_struct *work);
二、声明和初始化工作队列入口项
DECLARE_DELAYED_WORK(jack_work,jack_func); //DECLARE_WORK(jack_work,jack_func);
三、在需要的地方调用
schedule_delayed_work(&jack_work,HZ); //schedule_work(&jack_work);
四、删除队列
cancel_delayed_work(&jack_work); //cancel_work_sync(&jack_work);//注意:没有cancel_work这个函数
初始化有两种方法。
一种为静态方法:
#define DECLARE_WORK(n, f) \
struct work_struct n = __WORK_INITIALIZER(n, f)
#define __WORK_INITIALIZER(n, f) { \
.data = WORK_DATA_INIT(), \
.entry = { &(n).entry, &(n).entry }, \
.func = (f), \
__WORK_INIT_LOCKDEP_MAP(#n, &(n)) \
}
另一种为动态方法:
#define INIT_WORK(_work, _func) \
do { \
(_work)->data = (atomic_long_t) WORK_DATA_INIT(); \
INIT_LIST_HEAD(&(_work)->entry); \
PREPARE_WORK((_work), (_func)); \
} while (0)
#endif
DECLARE_WORK和INIT_WORK可以互替,但是使用INIT_WORK时一定要先定义work_struct结构体,如
static struct work_struct ssd2531_wq_updateEvn;
INIT_WORK(&ssd2531_wq_updateEvn, ssd2531_do_work_updateEvn);
DECLARE_WORK(ssd2531_wq_updateEvn, ssd2531_do_work_updateEvn);
同理,DECLARE_DELAYED_WORK和INIT_DELAYED_WORK也可以互替
schedule_work和queue_work可以互替使用
create_workqueue 与 create_singlethread_workqueue 的区别
create_workqueue 内核会在系统中的每个处理器上为该工作队列创建专用的线程,在许多情况下,众多的线程可能会对性能具有某种程度的杀伤力,
因此如果单个工作线程足够使用,那么应该使用 create_singlethread_workqueue