zoukankan      html  css  js  c++  java
  • 【面试】上中断和下中断

    翻看笔记发现之前的面试不会题目,搜索一下很有学问。

    中断跟函数栈很像,都需要保存现场,然后恢复现场,那区别在哪里呢?对中断的理解,之前在听一个中断培训的时候,想到这个有意思的问题。

    中断跟函数栈区别在于中断是不可预料的,所以发生中断时要全部保存当前现场,中断处理完恢复现场。而函数栈是可预料的,什么时候调用,从哪里调用都是已知的,那只需要保存必要的信息即可。

    中断的概念:一个"中断"仅仅是一个信号,当硬件需要获得处理器对它的关注时,就可以发送这个信号。内核维护了一个中断信号线的注册表,该注册表类似于I/O端口的注册表。
    上半部的功能是响应中断。下半部的功能是处理比较复杂的过程。下半部和上半部最大的区别是可中断,而上半部却不可中断。
    上半部只是将下半部排到了它们所负责的设备中断的处理队列中去,然后就不做其它的处理了。上半部之所以快,是因为它是完全屏蔽中断的,如果它没有执行完,其他中断就不能及时地处理,只能等到这个中断处理程序执行完毕以后。所以要尽可能多的对设备产生的中断进行服务和处理,中断响应程序就一定要快。


    经典网卡来举例,在linux内核中,当网卡一旦接受到数据,网卡会通过中断告诉内核处理数据,内核会在网卡中断处理函数(上半部)执行一些网卡硬件的必要设置,因为这是在中断响应后急切要干的事情。接着,内核调用对应的下半部函数来处理网卡接收到的数据,因为数据处理没必要在中断处理函数里面马上执行,可以将中断让出来做更紧迫的事情。

    可以有三种方法来实现下半部:软中断、tasklet和等待队列。

    1. 软中断
      软中断一般很少用于实现下半部,但tasklet是通过软中断实现的,所以先介绍软中断。字面理解,软中断就是软件实现的异步中断,它的优先级比硬中断低,但比普通进程优先级高,同时,它和硬中断一样不能休眠。
      软中断是在编译时候静态分配的,要用软中断必须修改内核代码。
    2. tasklet
      上面的介绍看到,软中断实现下半部的方法很麻烦,一般是不会使用的。一般,我们使用tasklet——利用软中断实现的下半部机制。
      在介绍软中断索引号的时候,有两个用于实现tasklet的软中断索引号:HI_SOFTIRQ和TASKLET_SOFTIRQ。两个tasklet唯一的区别就是优先级的大小,一般使用TAKSLET_SOFTIRQ。
      通过软中断(tasklet也是软中断的一种实现形式)机制来实现中断下半部。使用软中断实现的优缺点很明显:
      优点:运行在软中断上下文,优先级比普通进程高,调度速度快。
      缺点:由于处于中断上下文,所以不能睡眠。
      也许有人会问,那软中断和tasklet有什么区别?
      个人理解,tasklet是基于软中断实现的,基本上和软中断相同。但有一点不一样,如果在多处理器的情况下,内核不能保证软中断在哪个处理器上运行(听起来像废话),所以,软中断之间需要考虑共享资源的保护。而在tasklet,内核可以保证,两个同类型(TASKLET_SOFTIRQ和HI_SOFTIRQ)的tasklet不能同时执行,那就说明,同类型tasklet之间,可以不考虑同类型tasklet之间的并发情况。
      一般的,优先考虑使用tasklet。
    3. 工作队列完全不同,它是靠内核线程实现的。
      简单来说,软中断和tasklet优先级较高,性能较好,调度快,但不能睡眠。而工作队列是内核的进程调度,相对来说较慢,但能睡眠。所以,如果你的下半部需要睡眠,那只能选择动作队列。否则最好用tasklet。

    网卡中断理解

    参考:从中断说起

    从kernel层面将,事件产生有可能不是由硬件中断触发的,在一定情况下kernel的确会轮询,因为响应硬件中断是一个成本比较高的操作。
    以网卡为例,当数据量很少的时候,每来一个数据包网卡都回产生一个中断,kernel响应这个中断,从网卡缓冲区中读出数据放进协议栈处理,当满足一定条件时,kernel回调用户代码,这里的"回调"一般情况下是指从一个kernel syscall中返回(在此之前用户代码一直处于block状态)。
    当数据量很大时,每个包都产生一个中断就划不来了,此时kernel可以启动interrupt coalescing机制,让网卡做中断合并,也就是说来足够多的数据包或者等待一个timeout才会产生一个中断,kernel在响应中断时会把所有数据一起读出来处理,这样可以有效的降低中断次数。
    当数据量更大时,网卡缓冲区里几乎总是有未处理的数据,此时kernel干脆会禁掉网卡的中断,切换到轮询处理的模式,说白了就是跑一个忙循环不停地读网卡缓冲区里的数据,这样综合开销更低

  • 相关阅读:
    C#获取远程客户端IP
    .NET 中的对象序列化
    架构师
    如何在删除并重新安装 IIS 之后修复 IIS 映射
    Web.config里设置upload文件大小限制的属性是什么来着?在哪个Section里?
    ASP.net security
    如何优化JavaScript脚本的性能
    关于session丢失原因的分析
    浅谈对象的序列化(Serialize)
    微软软件架构师培训
  • 原文地址:https://www.cnblogs.com/quantumplan/p/9251455.html
Copyright © 2011-2022 走看看