linux工作队列


在Linux内核中,对下半部(或者说推后执行的工作)的处理方式有好几种,包括BH(bottom half),软中断,Tasklets和工作队列等等。在2.6内核中,大名鼎鼎的BH处理被废除,新增了更方便的工作队列。工作队列的方便之处在于它把工作推后,交由一个内核线程去执行,这个内核线程总会在进程上下文执行,因此,它就可以很方便的持有信号量(semaphore),当然也可以允许睡眠。
内核对工作队列的处理是通过工作者线程完成的。工作者线程在一般情况下处于睡眠状态,当我们把需要推迟执行的工作注册到工作队列中之后,唤醒工作者线程会遍历工作队列中的每个待处理的工作,并执行工作队列结构work_struct中的func函数。这里涉及到两个概念:工作者线程和工作队列。首先看看我们最关心的工作队列。
struct work_struct *delayed_work;
INIT_WORK(delayed_work, delayed_work_handler, data);
schedule_work(delayed_work);
delayed_work是我们声明的工作队列;通过INIT_WORK对工作队列进行初始化,delayed_work_handler是工作队列的处理函数,data是传递给处理函数的参数;最后调用schedule_work唤醒工作者线程处理推后执行的工作。如果需要经过一段延迟以后再执行工作,可以调用:
schedule_delayed_work(delayed_work, delay);    //delay 是需要延迟的节拍数
另外还有一种静态创建工作队列的方式:
DECLARE_WORK(name, void (*func) (void *), void *data);
大部分情况下我们了解到这里已经足够了。工作者线程可以放心的交给内核去完成。对于工作者线程的使用有两种方式,一是直接使用内核中每个CPU对应的一个缺省工作者线程envents/n(n代表CPU的序号,从0开始);再者就是自己创建一个专用的工作者线程。对于通常情况下,驱动开发者是不必关心工作者线程的,缺省的工作者线程能够做的很好。如果缺省的队列不能满足要求,自己创建一个工作者线程也很简单,只需要调用:
struct workqueue_struct *create_workqueue(const char *name);

struct workqueue_struct *create_freezable_workqueue(const char *name);

struct workqueue_struct *create_singlethread_workqueue(const char *name);this function creates a signal thread workqueue. which has one dedicated processes("kernel threads"), which runfunctions submitted to the queue.

调度时使用如下函数:
int queue_work(struct workqueue_struct *wq, struct work_struct *work);  

int queue_delayed_work(struct workqueue_struct *wq, struct work_struct *work, unsigned long delay);
它们与schedule_work()以及schedule_delayed_work()是类似的。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值