美文网首页程序员技术栈读书
一文带你彻底弄懂linux的中断

一文带你彻底弄懂linux的中断

作者: 盗火侠 | 来源:发表于2019-05-03 22:30 被阅读23次

    日更,今天聊一个技术问题:操作系统的中断。

    中断是啥:从订外卖说起

    首先,这里声明一下,以下比喻并非我原创,摘自极客时间我购买的专栏《Linux性能优化实战》,我略有扩充。

    假如你订了份外卖,没有任何方法获取外卖员何时会过来(就好像原始社会),且外卖员不会等你,到达后看到门口没有人就会离开。这时候你就只能不停地去门口查看,不能做其他事情。你会不会很崩溃😃?

    后来你想了个办法,下单时跟配送员约好,他到了就打电话给你。那么你就可以去忙别的事情,直到电话一响,去取就是了。

    非常容易理解吧?那么你能猜出来上面的例子中,哪部分对应的是中断吗?是的,就是接电话和取外卖。假如你正在写文章,电话一响,你就被打断了。

    Linux中的中断定义就是:中断是系统用来响应硬件设备请求的一种机制,它会打断正常进程的调度,转而调用内核中的中断处理程序来响应硬件设备的请求。

    为啥要有中断

    因为有了电话约定,你就不必苦苦等待,可以做很多其他事情,例如写文章啦、打游戏啦、陪亲人啦都可以。毫无疑问,这会让你在相同的时间里做更多的事情。对应到操作系统,中断作为一种异步事件处理机制,可以让CPU抽出身来处理其他工作,从而极大提高并发处理能力。

    这是现代多任务操作系统的一个最重要的特点。

    Linux的中断特点

    现在你知道了,中断会打断你手中的事情,例如你正在写作,电话一响,你就必须去取外卖。如果你足够细心,你会发现一个问题,例如:
    我脑海中的灵感正如泉涌,如果取外卖花了我太长时间(例如配送员被小区保安拦住不让进,我要跑到大门口去取),那么这个体验岂不是很糟糕?

    为了应对这种花费太多时间较差的情况,你想到了让外卖小哥先放到保安室,然后他可以自行离开。你也可以不必着急去取,写完文章再去取也不迟是吧?

    Linux为了处理这种情况,当然也考虑到了这点。Linux把中断分成了两个阶段:上半部下半部

    • 上半部:接电话。快速处理,在屏蔽其他中断模式下运行(可以理解为你正在打电话,其他人再打就会占线打不通,被屏蔽),主要处理跟硬件相关或时间敏感的工作。
    • 下半部:去取外卖。通常是交由内核线程去运行,主要处理上半部分未完成的工作。这部分会被放到工作队列里异步执行。

    如果你熟悉多线程编程,就很容易理解了,上半部分是临界区(某一时刻只能有一个线程据有),下半部分则比较自由了,可以并行,可以异步等等。

    那么,硬中断和软中断都是什么鬼?中断服务程序呢?

    上面知道了上半部下半部之后,其实可以粗略地理解为:上半部=硬中断;下半部=软中断

    硬中断 上半部,硬件设备的中断,快速处理,通常很短.
    软中断 下半部,或一些内核自定义事件(如网络收发,定时,调度,RCU锁),内核线程执行.

    中断服务程序就是中断一旦发生,就会去执行的代码块。软硬中断都会有各自的中断服务程序。它们的特点是比较简短(尤其硬中断,屏蔽模式可能导致其他中断丢失)。

    中断和CPU使用率关系

    �我们使用top命令,第一行输出:

    $ top
    %Cpu(s):  0.0 us,  0.2 sy,  0.0 ni, 99.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    ...(省略)...
    

    第一行显示的就是CPU使用率,我们知道:
    CPU总使用率 = 除idle(id)之外的所有使用率之和 = us + sy + ni + wa + hi + si +st
    其中hi表示硬中断(hardware interrupts),si表示软中断(software interrupts)。
    所以,如果hisi升高,也必然会导致CPU使用率升高哟。反向推理也很容易理解,中断就意味着切换,切换就意味着开销,所以中断肯定是有负载的。

    查看linux下的软硬中断种类及发生的次数,可以查看:

    • /proc/interrupts 提供了开机以来硬中断的运行情况;
    • /proc/softirqs 提供了开机以来软中断的运行情况.
      例如查看软中断:
    $ cat /proc/softirqs
                        CPU0       CPU1
              HI:          0          0
           TIMER:     811613    1972736
          NET_TX:         49          7
          NET_RX:    1136736    1506885
           BLOCK:          0          0
        IRQ_POLL:          0          0
         TASKLET:     304787       3691
           SCHED:     689718    1897539
         HRTIMER:          0          0
             RCU:    1330771    1354737
    
    • 第一列展示的是软中断的类型,共10个,如NET_RX表示网络接收中断;NET_TX表示网络发送中断;RCU表示Read-Copy Update缩写,是linux中最常用的锁之一.
    • 第二列及以后的表示在每个CPU上的分布.通常,同一种中断在不同CPU上的累计次数应该差不多,都在同一个数量级上.除了TASKLET.

    什么是TASKLET:最常用的软中断的一种实现,简单易用,每个TASKLET只运行一次就会结束,并且只在它的函数所在的CPU上运行.这意味着,这种轻量级中断会导致调度不均衡,会导致在多个CPU上并行带来性能限制.

    再来一个更常用的例子:网卡接收数据

    1. 上半部:网卡接收到数据包时,会通过硬件中断来通知内核有新的数据到了.此时内核就调用中断处理程序来响应它:把网卡的数据读取到内存中,然后更新一下寄存器状态(表示数据已经读完),然后再发送软中断,进入下半部.
    2. 下半部:(某一时刻)下半部信号被唤醒,则从内存中取到数据,按照协议栈逐层解析和处理,最后送给应用程序,中断完毕.

    划重点:总结

    1. 中断是系统用来响应硬件设备请求的一种机制,它会打断正常进程,转而调用内核中的中断处理程序来响应硬件设备的请求。
    2. 中断是一种异步的事件处理机制,提高系统并发能力。
    3. linux把中断分为两部分:上半部=硬中断,下半部=软中断。硬中断会开启屏蔽模式,所以大都简短以尽快结束;软中断可以异步(延迟)执行,自由度较大。
    4. 如果你的CPU升高,要看看是不是中断引起的,如果是,看看是什么类型中断,然后找出制造这种中断的罪魁祸首(进程)。

    相关文章

      网友评论

        本文标题:一文带你彻底弄懂linux的中断

        本文链接:https://www.haomeiwen.com/subject/tinznqtx.html