Linux-怎么理解軟中斷

從"取外賣(mài)"看中斷

中斷是系統(tǒng)用來(lái)響應(yīng)硬件設(shè)備請(qǐng)求的一種機(jī)制,它會(huì)打斷進(jìn)程的正常調(diào)度和執(zhí)行胁塞,然后調(diào)用內(nèi)核中的中斷處理程序來(lái)響應(yīng)設(shè)備的請(qǐng)求。

你可能要問(wèn)了压语,為什么要有中斷呢啸罢?我可以舉個(gè)生活中的例子,讓感受一下中斷的魅力胎食。

比如你訂了一份外賣(mài)扰才,但是不確定外賣(mài)什么時(shí)候送到,也沒(méi)有別的方法了解外賣(mài)的進(jìn)度厕怜,但是衩匣,配送員送外賣(mài)是不等人的蕾总,到了你這兒沒(méi)人取的話(huà),就直接走人了琅捏,所以你只能苦苦等著生百,時(shí)不時(shí)去門(mén)口看看外賣(mài)送到?jīng)],而不能干其他事情柄延。

不過(guò)呢蚀浆,如果在訂外賣(mài)的時(shí)候,你就跟配送員約定好搜吧,讓他送到后給你打個(gè)電話(huà)市俊,那你就不用苦苦等待了,就可以去忙別的事情滤奈,直到電話(huà)一響摆昧,接電話(huà)、取外賣(mài)就可以了僵刮。

這里的“打電話(huà)”据忘,其實(shí)就是一個(gè)中斷。沒(méi)接到電話(huà)的時(shí)候搞糕,你可以做其他的事情勇吊;只有接到了電話(huà)(也就是發(fā)生中斷),你才要進(jìn)行另一個(gè)動(dòng)作:取外賣(mài)窍仰。

這個(gè)例子你就可以發(fā)現(xiàn)汉规,中斷其實(shí)是一種異步的事件處理機(jī)制,可以提高系統(tǒng)的并發(fā)處理能力驹吮。

由于中斷處理程序會(huì)打斷其他進(jìn)程的運(yùn)行针史,所以,為了減少對(duì)正常進(jìn)程運(yùn)行調(diào)度的影響碟狞,中斷處理程序就需要盡可能快地運(yùn)行啄枕。如果中斷本身要做的事情不多,那么處理起來(lái)也不會(huì)有太大問(wèn)題族沃;但如果中斷要處理的事情很多频祝,中斷服務(wù)程序就有可能要運(yùn)行很長(zhǎng)時(shí)間。

特別是脆淹,中斷處理程序在響應(yīng)中斷時(shí)常空,還會(huì)臨時(shí)關(guān)閉中斷。這就會(huì)導(dǎo)致上一次中斷處理完成之前盖溺,其他中斷都不能響應(yīng)漓糙,也就是說(shuō)中斷有可能會(huì)丟失。

那么還是以取外賣(mài)為例烘嘱。假如你訂了 2 份外賣(mài)昆禽,一份主食和一份飲料蝗蛙,并且是由 2 個(gè)不同的配送員來(lái)配送。這次你不用時(shí)時(shí)等待著醉鳖,兩份外賣(mài)都約定了電話(huà)取外賣(mài)的方式歼郭。但是,問(wèn)題又來(lái)了辐棒。

當(dāng)?shù)谝环萃赓u(mài)送到時(shí)病曾,配送員給你打了個(gè)長(zhǎng)長(zhǎng)的電話(huà),商量發(fā)票的處理方式漾根。與此同時(shí)泰涂,第二個(gè)配送員也到了,也想給你打電話(huà)辐怕。

但是很明顯逼蒙,因?yàn)殡娫?huà)占線(xiàn)(也就是關(guān)閉了中斷響應(yīng)),第二個(gè)配送員的電話(huà)是打不通的寄疏。所以是牢,第二個(gè)配送員很可能試幾次后就走掉了(也就是丟失了一次中斷)。

軟中斷

如果你弄清楚了“取外賣(mài)”的模式陕截,那對(duì)系統(tǒng)的中斷機(jī)制就很容易理解了驳棱。事實(shí)上,為了解決中斷處理程序執(zhí)行過(guò)長(zhǎng)和中斷丟失的問(wèn)題农曲,Linux 將中斷處理過(guò)程分成了兩個(gè)階段社搅,也就是上半部和下半部:

  • 上半部用來(lái)快速處理中斷,它在中斷禁止模式下運(yùn)行乳规,主要處理跟硬件緊密相關(guān)的或時(shí)間敏感的工作形葬。
  • 下半部用來(lái)延遲處理上半部未完成的工作,通常以?xún)?nèi)核線(xiàn)程的方式運(yùn)行暮的。

比如說(shuō)前面取外賣(mài)的例子笙以,上半部就是你接聽(tīng)電話(huà),告訴配送員你已經(jīng)知道了冻辩,其他事兒見(jiàn)面再說(shuō)猖腕,然后電話(huà)就可以?huà)鞌嗔耍幌掳氩坎攀侨⊥赓u(mài)的動(dòng)作微猖,以及見(jiàn)面后商量發(fā)票處理的動(dòng)作谈息。

這樣缘屹,第一個(gè)配送員不會(huì)占用你太多時(shí)間凛剥,當(dāng)?shù)诙€(gè)配送員過(guò)來(lái)時(shí),照樣能正常打通你的電話(huà)轻姿。

除了取外賣(mài)犁珠,我再舉個(gè)最常見(jiàn)的網(wǎng)卡接收數(shù)據(jù)包的例子逻炊,讓你更好地理解。

網(wǎng)卡接收到數(shù)據(jù)包后犁享,會(huì)通過(guò)硬件中斷的方式余素,通知內(nèi)核有新的數(shù)據(jù)到了。這時(shí)炊昆,內(nèi)核就應(yīng)該調(diào)用中斷處理程序來(lái)響應(yīng)它桨吊。你可以自己先想一下,這種情況下的上半部和下半部分別負(fù)責(zé)什么工作呢凤巨?

對(duì)上半部來(lái)說(shuō)视乐,既然是快速處理,其實(shí)就是要把網(wǎng)卡的數(shù)據(jù)讀到內(nèi)存中敢茁,然后更新一下硬件寄存器的狀態(tài)(表示數(shù)據(jù)已經(jīng)讀好了)佑淀,最后再發(fā)送一個(gè)軟中斷信號(hào),通知下半部做進(jìn)一步的處理彰檬。

而下半部被軟中斷信號(hào)喚醒后伸刃,需要從內(nèi)存中找到網(wǎng)絡(luò)數(shù)據(jù),再按照網(wǎng)絡(luò)協(xié)議棧逢倍,對(duì)數(shù)據(jù)進(jìn)行逐層解析和處理捧颅,直到把它送給應(yīng)用程序。

所以较雕,這兩個(gè)階段你也可以這樣理解:

  • 上半部直接處理硬件請(qǐng)求隘道,也就是我們常說(shuō)的硬中斷,特點(diǎn)是快速執(zhí)行郎笆;
  • 而下半部則是由內(nèi)核觸發(fā)谭梗,也就是我們常說(shuō)的軟中斷,特點(diǎn)是延遲執(zhí)行宛蚓。

實(shí)際上激捏,上半部會(huì)打斷 CPU 正在執(zhí)行的任務(wù),然后立即執(zhí)行中斷處理程序凄吏。而下半部以?xún)?nèi)核線(xiàn)程的方式執(zhí)行远舅,并且每個(gè) CPU 都對(duì)應(yīng)一個(gè)軟中斷內(nèi)核線(xiàn)程,名字為 “ksoftirqd/CPU 編號(hào)”痕钢,比如說(shuō)图柏, 0 號(hào) CPU 對(duì)應(yīng)的軟中斷內(nèi)核線(xiàn)程的名字就是 ksoftirqd/0。

不過(guò)要注意的是任连,軟中斷不只包括了剛剛所講的硬件設(shè)備中斷處理程序的下半部蚤吹,一些內(nèi)核自定義的事件也屬于軟中斷,比如內(nèi)核調(diào)度和 RCU 鎖(Read-Copy Update 的縮寫(xiě),RCU 是 Linux 內(nèi)核中最常用的鎖之一)等裁着。

查看軟中斷和內(nèi)核線(xiàn)程

不知道你還記不記得繁涂,前面提到過(guò)的 proc 文件系統(tǒng)。它是一種內(nèi)核空間和用戶(hù)空間進(jìn)行通信的機(jī)制二驰,可以用來(lái)查看內(nèi)核的數(shù)據(jù)結(jié)構(gòu)扔罪,或者用來(lái)動(dòng)態(tài)修改內(nèi)核的配置。其中:

  • /proc/softirqs 提供了軟中斷的運(yùn)行情況桶雀;
  • /proc/interrupts 提供了硬中斷的運(yùn)行情況矿酵。

運(yùn)行下面的命令,查看 /proc/softirqs 文件的內(nèi)容矗积,你就可以看到各種類(lèi)型軟中斷在不同 CPU 上的累積運(yùn)行次數(shù):

$ 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

在查看 /proc/softirqs 文件內(nèi)容時(shí)坏瘩,你要特別注意以下這兩點(diǎn)。
第一漠魏,要注意軟中斷的類(lèi)型倔矾,也就是這個(gè)界面中第一列的內(nèi)容。從第一列你可以看到柱锹,軟中斷包括了 10 個(gè)類(lèi)別哪自,分別對(duì)應(yīng)不同的工作類(lèi)型。比如 NET_RX 表示網(wǎng)絡(luò)接收中斷禁熏,而 NET_TX 表示網(wǎng)絡(luò)發(fā)送中斷壤巷。

第二,要注意同一種軟中斷在不同 CPU 上的分布情況瞧毙,也就是同一行的內(nèi)容胧华。正常情況下,同一種中斷在不同 CPU 上的累積次數(shù)應(yīng)該差不多宙彪。比如這個(gè)界面中矩动,NET_RX 在 CPU0 和 CPU1 上的中斷次數(shù)基本是同一個(gè)數(shù)量級(jí),相差不大释漆。

不過(guò)你可能發(fā)現(xiàn)悲没,TASKLET 在不同 CPU 上的分布并不均勻。TASKLET 是最常用的軟中斷實(shí)現(xiàn)機(jī)制男图,每個(gè) TASKLET 只運(yùn)行一次就會(huì)結(jié)束 示姿,并且只在調(diào)用它的函數(shù)所在的 CPU 上運(yùn)行。

因此逊笆,使用 TASKLET 特別簡(jiǎn)便栈戳,當(dāng)然也會(huì)存在一些問(wèn)題,比如說(shuō)由于只在一個(gè) CPU 上運(yùn)行導(dǎo)致的調(diào)度不均衡难裆,再比如因?yàn)椴荒茉诙鄠€(gè) CPU 上并行運(yùn)行帶來(lái)了性能限制子檀。

另外,剛剛提到過(guò),軟中斷實(shí)際上是以?xún)?nèi)核線(xiàn)程的方式運(yùn)行的命锄,每個(gè) CPU 都對(duì)應(yīng)一個(gè)軟中斷內(nèi)核線(xiàn)程,這個(gè)軟中斷內(nèi)核線(xiàn)程就叫做 ksoftirqd/CPU 編號(hào)偏化。那要怎么查看這些線(xiàn)程的運(yùn)行狀況呢脐恩?

其實(shí)用 ps 命令就可以做到,比如執(zhí)行下面的指令:

$ ps aux | grep softirq
root         7  0.0  0.0      0     0 ?        S    Oct10   0:01 [ksoftirqd/0]
root        16  0.0  0.0      0     0 ?        S    Oct10   0:01 [ksoftirqd/1]

注意侦讨,這些線(xiàn)程的名字外面都有中括號(hào)驶冒,這說(shuō)明 ps 無(wú)法獲取它們的命令行參數(shù)(cmline)。一般來(lái)說(shuō)韵卤,ps 的輸出中骗污,名字括在中括號(hào)里的,一般都是內(nèi)核線(xiàn)程沈条。

小結(jié)

Linux 中的中斷處理程序分為上半部和下半部:
上半部對(duì)應(yīng)硬件中斷需忿,用來(lái)快速處理中斷。
下半部對(duì)應(yīng)軟中斷蜡歹,用來(lái)異步處理上半部未完成的工作屋厘。

Linux 中的軟中斷包括網(wǎng)絡(luò)收發(fā)、定時(shí)月而、調(diào)度汗洒、RCU 鎖等各種類(lèi)型,可以通過(guò)查看 /proc/softirqs 來(lái)觀(guān)察軟中斷的運(yùn)行情況父款。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末溢谤,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子憨攒,更是在濱河造成了極大的恐慌世杀,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肝集,死亡現(xiàn)場(chǎng)離奇詭異玫坛,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)包晰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)湿镀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人伐憾,你說(shuō)我怎么就攤上這事勉痴。” “怎么了树肃?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵蒸矛,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)雏掠,這世上最難降的妖魔是什么斩祭? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮乡话,結(jié)果婚禮上摧玫,老公的妹妹穿的比我還像新娘。我一直安慰自己绑青,他們只是感情好诬像,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著闸婴,像睡著了一般坏挠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上邪乍,一...
    開(kāi)封第一講書(shū)人閱讀 49,046評(píng)論 1 285
  • 那天降狠,我揣著相機(jī)與錄音,去河邊找鬼庇楞。 笑死喊熟,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的姐刁。 我是一名探鬼主播芥牌,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼聂使!你這毒婦竟也來(lái)了壁拉?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤柏靶,失蹤者是張志新(化名)和其女友劉穎弃理,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體屎蜓,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡痘昌,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了炬转。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辆苔。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖扼劈,靈堂內(nèi)的尸體忽然破棺而出驻啤,到底是詐尸還是另有隱情,我是刑警寧澤荐吵,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布骑冗,位于F島的核電站赊瞬,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏贼涩。R本人自食惡果不足惜巧涧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望遥倦。 院中可真熱鬧谤绳,春花似錦、人聲如沸谊迄。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)统诺。三九已至,卻和暖如春疑俭,著一層夾襖步出監(jiān)牢的瞬間粮呢,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工钞艇, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留啄寡,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓哩照,卻偏偏與公主長(zhǎng)得像挺物,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子飘弧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345