第七章 下半部和推后执行的工作

  1. 在2.6版本中有三种不同形式的下半部机制:
    1. 软中断:32个静态定义的下半部接口,可以在所有处理器上同时执行。
    2. tasklet:基于软中断,动态创建的下半部机制。不同类型的tasklet可以在不同处理器同时执行,但类型相同的不能。
    3. 工作队列:对推后执行的工作排队,稍后在进程上下文执行。
    4. BH和任务队列已被弃用
  2. 软中断:
    1. 软中断不会抢占另一个软中断,不过其他软中断可以在其他处理器上同时执行
    2. 只有中断处理程序可以抢占软中断。
    3. 在下列地方,待处理的软中断会被检查和执行:
      1. 从一个硬件中断代码处返回时
      2. 在ksoftirqd内核线程中
      3. 在那些显示检查和执行待处理的软中断代码中,如网络子系统中。
    4. 使用软中断的步骤
      1. 分配索引
      2. 注册软中断处理程序:open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL);
      3. 触发你的软中断:
        1. raise_softirq(NET_TX_SOFTIRQ);
        2. raise_softirq_irqoff(NET_TX_SOFTIRQ);//中断已经被禁止的情况下调用
  3. tasklet:
    1. 由两类软中断代表:HI_SOFTIRQ和TASKLET_SOFTIRQ。前者优先级高。
    2. 已调度的tasklet(等同于被触发的软中断)存放在两个单处理器数据结构:tasklet_vec和tasklet_hi_vec。这两个都是由tasklet_struct结构体构成的链表
    3. tasklet由tasklet_schedule()和tasklet_hi_schedule()函数进行调度(和唤醒一个意思,都是将此下半部设置为待执行状态,一般在上半部调用)
    4. tasklet_action()和tasklet_hi_action()是处理tasklet的函数
    5. 使用tasklet
      1. 声明自己的tasklet
        1. 静态创建:
          1. DECLARE_TASKLET(name, func, data)
          2. DECLARE_TASKLET_DISABLED(name, func, data)
        2. 动态创建:
          1. tasklet_init(t, tasklet_handler, dev)
      2. 编写自己的tasklet
        1. 函数类型:void task_let_handler(unsigned long data)
        2. 不能睡眠,不能使用信号量等阻塞式的函数
      3. 调度自己的tasklet
        1. 通过调用tasklet_schedule(&my_tasklet)
  4. ksoftirqd
    1. 每个处理器有一个名为ksoftirqd/n的线程,在最低的优先级上运行(nice值是19)
  5. 工作队列
    1. 总是会在进程上下文执行,允许重新调度甚至睡眠
    2. 可以让驱动程序创建一个专门的工作者线程来处理这些工作。默认的工作者线程叫做events/n
    3. 使用工作队列
      1. 创建推后的工作
        1. 静态创建:DECLARE_WORK(name, void (*func) (void *), void *data)
        2. 动态创建:INIT_WORK(struct work_struct *work, void (*func) (void *), void *data)
      2. 工作队列处理函数
        1. 函数类型:void work_handler(void *data)
      3. 对工作进行调度
        1. 调用schedule_work(&work):立即调度,工作者线程唤醒就会执行
        2. 调用schedule_delayed_word(&work, delay):延迟delay指定的时钟节拍再调度
      4. 刷新操作
        1. void flush_scheduled_work(void):函数直到队列中所有对象都被执行后才返回
        2. int cancel_delayd_work(struct work_struct *work):取消schedule_delayed_word调度的工作
      5. 创建新的工作队列
        1. struct workqueue_struct *create_workqueue(const char *name):name用户内核线程的命名,会在每个处理器上都创建一个工作者线程
        2. 针对指定工作队列的接口:
          1. int queue_work(struct workqueue_struct *wq, struct work_struct *work)
          2. int queue_delayed_work(struct workqueue_struct *wq, struct work_struct *work, unsigned long delay)
          3. flush_workqueue(struct workqueue_struct *wq)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值