linux各种队列

普通队列
一、定义工作入口项
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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值