使用软中断

    软中断保留给系统中对时间要求最严格以及最重要的下半部使用。目前,只有两个子系统---网络和SCSI直接使用软中断。此外,内核定时器和taskelet都是建立在软中断上的。对于时间要求严格并能自己高效完成加锁工作的应用,软中断会是正确的选择。

     怎样使用软中断呢?

 

1.分配索引

 

在编译期间,可以通过<linux/interrupt.h>中定义的一个枚举类型来静态声明软中断。索引号小的软中断在索引号大的软中断之前执行。要添加新项的话根据赋予它的优先级来决定加入的位置而不是直接添加到列表末尾。

  1. /* PLEASE, avoid to allocate new softirqs, if you need not _really_ high
  2.    frequency threaded job scheduling. For almost all the purposes
  3.    tasklets are more than enough. F.e. all serial device BHs et
  4.    al. should be converted to tasklets, not to softirqs.
  5.  */
  6. enum
  7. {
  8.     HI_SOFTIRQ=0,
  9.     TIMER_SOFTIRQ,
  10.     NET_TX_SOFTIRQ,
  11.     NET_RX_SOFTIRQ,
  12.     BLOCK_SOFTIRQ,
  13.     TASKLET_SOFTIRQ,
  14.     SCHED_SOFTIRQ,
  15. #ifdef CONFIG_HIGH_RES_TIMERS
  16.     HRTIMER_SOFTIRQ,
  17. #endif
  18. };

2. 注册你的处理程序

 

    在运行时 通过调用open_softirq()注册软件处理程序,该函数有三个参数:软中断的索引号、处理函数和data域存放的数值:

 

  1. void open_softirq(int nr, void (*action)(struct softirq_action*), void *data)
  2. {
  3.     softirq_vec[nr].data = data;
  4.     softirq_vec[nr].action = action;
  5. }

3.触发你的软中断

  通过在枚举类型的列表中添加新项,调用open_softirq()进行注册之后,新的软中断处理程序就能够运行。raise_softirq()函数可以将一个软中断设置为挂起状态,让它在下次调用do_softirq()函数时投入运行:

  1. void fastcall raise_softirq(unsigned int nr)
  2. {
  3.     unsigned long flags;
  4.     local_irq_save(flags);
  5.     raise_softirq_irqoff(nr);
  6.     local_irq_restore(flags);
  7. }

该函数在触发一个软中断之前先要禁止中断,触发后再恢复原来的状态,如果中断本来就已经被禁止了,那么可以调用另一个函数raise_softirq_irqoff():

  1. /*
  2.  * This function must run with irqs disabled!
  3.  */
  4. inline fastcall void raise_softirq_irqoff(unsigned int nr)
  5. {
  6.     __raise_softirq_irqoff(nr);
  7.     /*
  8.      * If we're in an interrupt or softirq, we're done
  9.      * (this also catches softirq-disabled code). We will
  10.      * actually run the softirq once we return from
  11.      * the irq or softirq.
  12.      *
  13.      * Otherwise we wake up ksoftirqd to make sure we
  14.      * schedule the softirq soon.
  15.      */
  16.     if (!in_interrupt())
  17.         wakeup_softirqd();
  18. }
  1. #define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0)
  2. #define or_softirq_pending(x)  or_pda(__softirq_pending, (x))

在中断处理程序中触发软中断是最常见的形式。在这种情况下,中断处理程序执行硬件设备的相关操作,然后触发相应的软中断,最后退出。内核在执行完 中断处理程序之后,马上调用do_softirq()函数,于是软中断开始执行中断处理程序留给它要完成的剩余任务。

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Linux内核编程中,软中断(Softirqs)和工作队列(Workqueues)是两种常见的异步执行机制,它们用于处理需要延迟执行任务,但它们的使用场景和特性有所不同。 软中断: 1. 软中断是一种轻量级的上下文,用于延迟处理硬件中断服务程序中的非紧急工作。 2. 软中断在中断上下文之外执行,这意味着它们不会阻塞硬件中断。 3. 软中断是固定优先级的,并且是在中断上下文中执行的,因此它们必须非常迅速和高效。 4. 软中断适合处理时间敏感的任务,如网络数据包的接收和发送处理。 工作队列: 1. 工作队列将工作推送到内核线程中执行,因此它们运行在进程上下文中。 2. 工作队列可以阻塞,适合执行那些需要睡眠、等待或需要更长执行时间的任务。 3. 工作队列提供了更多灵活性,因为它们可以被不同的内核线程处理,包括它们自己的工作队列线程。 4. 工作队列适用于不能或不应该在中断上下文中执行的耗时任务,例如磁盘I/O操作。 使用软中断工作队列的决定因素包括: - 任务的紧急程度:需要快速执行且不会阻塞的任务应该使用软中断。 - 执行时间长度:耗时较长或者需要睡眠的任务应该使用工作队列。 - 是否需要睡眠:如果任务中需要睡眠或者等待,应该使用工作队列,因为软中断中不允许睡眠。 - 系统资源:如果系统资源紧张,应该更加谨慎地使用软中断,因为它们是在中断上下文中执行的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值