一、中断在生活的魅力centos
好比你订了一份外卖,可是不肯定外卖何时送到,也没有别的方法了解外卖的进度,可是,配送员送外卖是不等人的,
到了你这儿没人取的话,就直接走人了。因此你指能苦苦等着,时不时去门口看看外卖送到没,而不能干其余事情。bash
不过呢,若是你在订外卖的时候,你就跟配送员约定好,让他送到后给你打个电话,你就不用苦苦等待了,就能够去忙别的事情,
直到电话一响,接电话、取外卖就能够了网络
这里的"打电话",其实就是一个中断。没接到电话的时候,你能够作其余的事情;只有接到了电话(也就是发生中断),你才要进行另外一个动做:取外卖
这个例子你就能够发现,中断其实就是一种异步的事件处理机制,能够提升系统的并发处理能力并发
二、什么是中断?异步
中断其实就是一种异步的事件处理机制,能够提升系统的并发处理能力函数
三、为何要有中断呢?性能
能够提升系统的并发处理能力spa
一、因为中断处理程序会打断其余进程的运行,因此,为了减小对正常进程运行调度的影响,中断处理程序须要尽量快的运行命令行
二、若是中断自己作的事情很少,那么处理起来也不会又太大问题线程
三、但若是中断要处理的事情不少,中断服务程序就可能要运行很长时间
特别是,中断处理程序在响应中断时,还会临时关闭中断,这就会致使上一次中断处理完成以前,其余中断不能响应,也便是说中断有可能会丢失
一、假如你定了2分外卖,一份主食和一份饮料,而且是由2个不一样的配送员来配送。
二、两份外卖都约定了电话取外卖的方式,可是问题又来了
三、当第一份外卖送到的,配送员给你打了个长长的电话,商量发票的处理方式,
四、与此同时,第二个配送员也到了,也想给你打电话,可是很明显,由于电话占线(也就是关闭了中断响应)
五、第二个配送员的电话是打不通的。因此,第二个配送员极可能试了几回后就走掉了(也就是丢失了一次中断)
一、Linux 将中断处理过程分红两个阶段
二、分别是上半部用来快速处理中断和下半部分用来延迟处理上半部分未完成的工做
三、上半部用来快速处理中断:它在中断禁止模式下运行,只要处理跟硬件紧密相关的时间敏感的工做
四、下半部分用来延迟处理上半部分未完成的工做:一般一内核线程的方式运行
上半部就是你接电话,告诉配送员你已经知道了,其余事儿见面再说,而后电话就能够挂断了;
下半部才是取外卖的动做,以及见面后商量发票处理的动做
这样第一个配送员不会占用你太多时间,当第二个配送员过来时,照样能正常打通你的电话,
网卡接收到数据包后,会经过硬件中断的方式,通知内核有新的数据到了,这时,内核就应该调用中断处理程序来
响应它,你能够本身先想一下,这种状况下的上半部分和下半部分分别负责什么工做呢?
既然是快速处理,其实就是要把网卡的数据读到内存中,而后更新一下硬件寄存器的状态(标识数据已经读好了),最后再发送一个软中断信号,通知下半部作进一步的处理
被软中断信号唤醒后,须要从内存中找到网络数据,再按照网络协议栈,对数据进行逐层解析和处理,直到把它送给应用程序。
上半部分直接处理硬件请求,也就是咱们常说的硬中断,特色是快速执行
而下半部则是由内核触发,也就是咱们常说的软中断,特色是延迟执行
实际上,上半部会打断CPU正在执行的任务,而后当即执行中断处理程序,而下半部之内核线程的方式执行,而且每一个CPU都对应一个软中断
内核线程,名字为"ksoftirqd/CPU 编号" 好比0号CPU对应的软中断内核线程的名字就是ksoftirqd/0
软中断不仅包括了刚刚所讲的硬件设备中断处理程序的下半部。一些内核自定义的时间也属于软中断,好比内核调度和RCU锁
(Read-Copy Update 的缩写,RCU 是 Linux 内核中最经常使用的锁之一)等。
Ubuntu 18.04
[root@localhost ~]# cat /proc/softirqs CPU0 CPU1 CPU2 CPU3 HI: 3 1 0 0 TIMER: 25265822 43447443 10082461 12874428 NET_TX: 387749 5 1927 1 NET_RX: 28946864 41272 32597 23383 BLOCK: 888 539 1296 1162217 BLOCK_IOPOLL: 0 0 0 0 TASKLET: 39231 9 110 1 SCHED: 21957135 40794916 7650486 10479809 HRTIMER: 0 0 0 0 RCU: 2925240 2746051 2401640 2383562
centos
[root@luoahong ~]# cat /proc/softirqs CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 CPU8 CPU9 CPU10 CPU11 CPU12 CPU13 CPU14 CPU15 CPU16 CPU17 CPU18 CPU19 CPU20 CPU21 CPU22 CPU23 CPU24 CPU25 CPU26 CPU27 CPU28 CPU29 CPU30 CPU31 CPU32 CPU33 CPU34 CPU35 CPU36 CPU37 CPU38 CPU39 CPU40CPU41 CPU42 CPU43 CPU44 CPU45 CPU46 CPU47 CPU48 CPU49 CPU50 CPU51 CPU52 CPU53 CPU54 CPU55 CPU56 CPU57 CPU58 CPU59 CPU60 CPU61 CPU62 CPU63 CPU64 CPU65 CPU66 CPU67 CPU68 CPU69 CPU70 CPU71 CPU72 CPU73 CPU74 CPU75 CPU76 CPU77 CPU78 CPU79 CPU80 CPU81 CPU82 CPU83 CPU84 CPU85 CPU86 CPU87 CPU88 CPU89 CPU90 CPU91 CPU92 CPU93 CPU94 CPU95 CPU96 CPU97 CPU98 CPU99 CPU100 CPU101 CPU102 CPU103 CPU104 CPU105 CPU106 CPU107 CPU108 CPU109 CPU110 CPU111 CPU112 CPU113 CPU114 CPU115 CPU116 CPU117 CPU118 CPU119 CPU120 CPU121 CPU122 CPU123 CPU124 CPU125 CPU126 CPU127 HI: 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 TIMER: 4699549 4940977 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 NET_TX: 4267 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 NET_RX: 605 102597 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 BLOCK: 4595883 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 BLOCK_IOPOLL: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 TASKLET: 56 1014 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 SCHED: 418267 475421 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 HRTIMER: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 RCU: 389674 288935 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
一、不过你可能发现,TASKLET在不一样CPU上的分布并不均匀,TASKLET是最经常使用的软中断实现机制,每TASKLET个只运行一次就会结束,而且只在调用它的函数所在的CPU上运行。
由于使用TASKLET特别简便,固然也会存在一些问题,好比说因为只在一个cpu上运行致使调度不均衡,再好比由于不能在多个CPU上并行运行带来了性能限制
二、另外,刚刚提到过,软中断其实是之内核线程的方式运行的,每一个CPU都对应一个软中断内核线程,这个软中断内核线程叫作ksoftirqd/CPU 编号。那要怎么查看这些线程的运行呢?
[root@luoahong ~]# ps aux | grep softirq root 3 0.2 0.0 0 0 ? S 11:09 0:43 [ksoftirqd/0] root 14 0.0 0.0 0 0 ? S 11:09 0:08 [ksoftirqd/1] root 19903 0.0 0.0 112712 976 pts/0 R+ 17:04 0:00 grep --color=auto softirq
注意:这些线程的名字外面都有中括号,这说明ps没法获取他们的命令行参数(cmline)。通常来讲,ps 的输出中,名字括在中括号里的,通常都是内核线程