tasklet workqueue使用

一、tasklet机制

1、原理

  • 类似内核定时器 ,调度一个任务稍后执行。主要用于中断的底半部
  • Tasklet是一个数据结构, 它指导内核在稍后CPU空闲的时间(但不能指定确定时间),使用一个用户定义的参数,执行一个用户定义的函数
  • 由内核线程——软中断(ksoftirqd/0)调度执行。在tasklet内不能睡眠
  • 运行在调度它们的同一个 CPU 上

2、tasklet使用的内核API

  • include <linux/interrupt.h>
  • struct tasklet_struct {
        void (*func)(unsigned long);
        unsigned long data;
        其它字段
    };
  • 完全初始化tasklet
    • void tasklet_init(struct tasklet_struct *t, void (*func)(ulong), ulong data);
    • DECLARE_TASKLET(name, func, data);
    • DECLARE_TASKLET_DISABLED(name, func, data);
  • void tasklet_schedule(struct tasklet_struct *t);
    • 将tasklet加入系统链表,即调度tasklet运行
    • tasklet执行后会自动退出系统链表,如需再次执行,需再次加入系统链表
  • void tasklet_hi_schedule(struct tasklet_struct *t);
    • 以高优先级调度tasklet
  • void tasklet_kill(struct tasklet_struct *t);
    • 将tasklet退出系统链表
  • void tasklet_disable(struct tasklet_struct *t);
  • void tasklet_enable(struct tasklet_struct *t);
    • tasklet在disable的状态下可以被tasklet_schedule,但该tasklet必须等到tasklet_enable后才能真正运行
    • tasklet_enable的次数必须与tasklet_disable的次数相等

三、Workqueue机制

1、原理

  • 类似Tasklet,提交一个work到OS的特定workqueue——events/0上,以便稍后执行。主要用于中断的底半部
  • work是一个数据结构, 它指导内核在稍后的时间(但不能指定确定时间)或至少延迟一个确定的时间后,执行一个用户定义的函数(不能指定参数)
  • 由内核线程——events/0调度执行
    • 内核线程——events/0不处于atomic context
  • 缺省运行在调度它们的同一个 CPU 上

# ps
  PID  Uid        VSZ Stat Command
    1 root       3092 S   init
    2 root            SW< [kthreadd]
    3 root            SWN [ksoftirqd/0]   //N表示低优先级, <表示高优先级
    4 root            SW< [events/0]
    5 root            SW< [khelper]
   41 root            SW< [kblockd/0]
   42 root            SW< [ksuspend_usbd]
   45 root            SW< [khubd]
   47 root            SW< [kseriod]
   59 root            SW  [pdflush]
   60 root            SW  [pdflush]
   61 root            SW< [kswapd0]
   62 root            SW< [aio/0]
  177 root            SW< [mtdblockd]
  226 root            SWN [jffs2_gcd_mtd2]
  248 root       1952 S   /usr/sbin/vsftpd
  249 root       3096 S   -sh
  250 root       3092 S   /usr/sbin/telnetd
  253 www        3092 S   /usr/sbin/httpd -h /www -u www
  256 root       3096 R   ps

2、Tasklet与Workqueue的区别

Tasklet

Workqueue

处于atomic context,不能sleep

不处于atomic context,可以sleep

运行在调度它们的同一个 CPU 上

默认运行在调度它们的同一个 CPU 上

不能指定确定时间进行调度

不能指定确定时间进行调度或指定至少延迟一个确定的时间后调度

只能提交给ksoftirqd/0

可以提交给events/0,也可以提交给自定义的workqueue

tasklet函数带参数

work函数不带参数

 

3、Workqueue API

  • DECLARE_WORK(name, void (*function)(work_struct *))
    • 编译时完全初始化一个work_struct
  • INIT_WORK(struct work_struct *work, void (*function)(work_struct *))
    • 完全初始化一个work_struct
  • int schedule_work(struct work_struct *work)
    • 将work提交给默认的kevent
  • •nt schedule_delayed_work(struct work_struct *work, ulong delay)
    • 将work提交给默认的kevent,但延后delay后调度
  • int cancel_delayed_work(struct work_struct *work);
    • 取消提交的work
  • void flush_scheduled_work(void)
    • 将kevent中的work全部取消
  • struct workqueue_struct *create_workqueue(const char *name)
  • struct workqueue_struct *create_singlethread_workqueue(const char *name)
    • 创建自己的workqueue,并与每个CPU(或单个CPU)绑定
  • int queue_work(struct workqueue_struct *queue, struct work_struct *work)
  • int queue_delayed_work(struct workqueue_struct *queue, struct work_struct *work, ulong delay)
    • 将work提交给queue
  • void flush_workqueue(struct workqueue_struct *queue)
    • 将queue中的work全部取消
  • void destroy_workqueue(struct workqueue_struct *queue)
    • 删除自己创建的queue
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值