一、中斷在生活的魅力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 的輸出中,名字括在中括號裏的,通常都是內核線程