Linux 中斷是一種非同步事件,它可以在任何時候發生,並且可以打破程式的正常執行流程。為了處理這些中斷,Linux 核心提供了一個通用的中斷處理機制。
#中斷實就是由硬體或軟體所發送的一種稱為IRQ(中斷請求)的訊號。
中斷允許讓設備,如鍵盤,串口卡,並口等設備表明它們需要CPU。
一旦CPU接收了中斷請求,CPU就會暫時停止執行正在執行的程序,並且呼叫一個稱為中斷處理器或中斷服務程序(interrupt service routine)的特定程式。
中斷服務程序或中斷處理器可以在中斷向量表中找到,而這個中斷向量表位於記憶體中的固定位址中。中斷被CPU處理後,就會恢復執行先前中斷的程式。
其實,在機器啟動的時候,系統就已經辨識了所有設備,也把對應的中斷處理器載入到中斷表中。
以下是請求CPU關注的兩種方式:
\1. 基於中斷
\2. 基於輪詢
所有的linux作業系統都是基於中斷驅動的。
當我們在鍵盤上按下一個按鍵時,鍵盤就會對CPU說,一個鍵已經被按下。在這種情況下,鍵盤的IRQ線路中的電壓就會發生一次變化,而這種電壓的變化就是來自設備的請求,就等於說這個設備有一個請求需要處理。
/proc/interrupts 檔案
在linux的機器上,/proc/interrupts這個檔案包含有關於哪些中斷正在使用和每個處理器各被中斷了多少次的資訊。
\# cat /proc/interrupts CPU0 CPU1 CPU2 CPU3 0: 3710374484 0 0 0 IO-APIC-edge timer 1: 20 0 0 0 IO-APIC-edge i8042 6: 5 0 0 0 IO-APIC-edge floppy 7: 0 0 0 0 IO-APIC-edge parport0 8: 0 0 0 0 IO-APIC-edge rtc 9: 0 0 0 0 IO-APIC-level acpi 12: 240 0 0 0 IO-APIC-edge i8042 14: 11200026 0 0 0 IO-APIC-edge ide0 51: 61281329 0 0 0 IO-APIC-level ioc0 59: 1 0 0 0 IO-APIC-level vmci 67: 19386473 0 0 0 IO-APIC-level eth0 75: 94595340 0 0 0 IO-APIC-level eth1 NMI: 0 0 0 0 LOC: 3737150067 3737142382 3737145101 3737144204 ERR: 0 MIS: 0
對上面文件的輸出,解釋如下:
● 第一列表示IRQ號
● 第二、三、四列表示對應的CPU核心中斷的次數。在上面的例子中,timer表示中斷名稱(為系統時鐘)。 3710374484表示CPU0中斷了3710374484次。 i8042表示控制鍵盤和滑鼠的鍵盤控制器。
● 對於像rtc(real time clock)這樣的中斷,CPU是不會被中斷的。因為RTC存在於電子設備中,是用來追蹤時間的。
● NMI和LOC是系統所使用的驅動,使用者無法存取和配置。
IRQ號決定了需要被CPU處理的優先權。 IRQ號越小意味著優先權越高。
例如,如果CPU同時接收了來自鍵盤和系統時鐘的中斷,那麼CPU首先會服務於系統時鐘,因為他的IRQ號碼是 0 。
● IRQ0 :系統時脈(不能改變)
● IRQ1 :鍵盤控制器(不能改變)
● IRQ3 :串列埠2的串列埠控制器(如有串列埠4,則其也使用此中斷)
● IRQ4 :串列埠1的串列埠控制器(如有串列埠3,則其也使用此中斷)
● IRQ5 :並口 2和3 或 聲卡
● IRQ6 :軟碟控制器
● IRQ7 : 並口1。它被用於印表機或如果沒有印表機,可以用於任何的並口。
而對於像操作桿(或稱為遊戲手把)上的CPU,它並不會等待裝置發送中斷。因為操作桿主要用於遊戲,操作桿的移動必須非常快,因此使用輪詢的方式檢測設備是否需要CPU的關注還是比較理想的。使用輪詢方式的缺點是CPU就處於忙碌等狀態,因為CPU會不停的多次檢查設備。但是需要注意的是在linux中,這種處理訊號的方式也是不可或缺的。
硬中斷
對於上文所討論的場景都是屬於硬中斷的例子。硬中斷主要分為兩種:
\1. 非屏蔽中斷(Non-maskable interrupts,即NMI):就像這種中斷類型的字面意思一樣,這種中斷是不可能被CPU忽略或取消的。 NMI是在單獨的中斷線路上進行發送的,它通常被用於關鍵性硬體發生的錯誤,如記憶體錯誤,風扇故障,溫度感測器故障等。
\2. 可屏蔽中斷(Maskable interrupts):這些中斷是可以被CPU忽略或延遲處理的。當快取控制器的外部針腳被觸發的時候就會產生這種類型的中斷,而中斷屏蔽暫存器就會將這樣的中斷屏蔽掉。我們可以將一個位元位元設為0,來停用在此針腳觸發的中斷。
軟中斷
這些中斷是在CPU執行指令(也就是說在進程正在運作的時候)的時候產生的,因為在執行指令時,CPU(確切的說應是在CPU中的運算器)本身會產生一個異常(此處的異常也可理解為軟中斷)。
例如,一個數字除以0(當然這是不可能的),此時就會導致一個divide-by-zero的異常,從而導致計算機將此計算取消或顯示一個錯誤的訊息。
在檔案/proc/stat中,包含了一些關於系統核心的統計信息,也包含了一些中斷資訊。
\# cat /proc/stat cpu 17028082 5536753 5081493 1735530500 42592308 90006 479750 0 cpu0 5769176 1170683 1495750 403368354 39406374 90006 284864 0 cpu1 3714389 1451937 1186134 444082258 1084780 0 64876 0 cpu2 3791544 1471013 1211868 443988514 1056981 0 64764 0 cpu3 3752971 1443119 1187740 444091373 1044172 0 65244 0 intr 417756956 --- Output Truncated
在intr這一行,顯示了自系統啟動以來所產生的中斷數。第一列表示所有被服務的中斷數。後續的每一列都表示一個特定中斷的總數。
SMP_AFFINITY
SMP是指对称多处理器。smp_affinity文件主要用于某个特定IRQ要绑定到哪个CPU核心上。在/proc/irq/IRQ_NUMBER/目录下都有一个smp_affinity文件,这个文件中,所表示的CPU核心以十六进制来表示的。例如,网卡的中断号是:
grep eth0 /proc/interrupts
67: 23834931 0 0 0 IO-APIC-level eth0
cat /proc/irq/67/smp_affinity
00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
上面的十六进制对应的十进制是1,也就是说所有的和网卡驱动相关的中断都是有CPU0来提供服务的。
我们可以通过手动改变smp_affinity文件中的值来将IRQ绑定到指定的CPU核心上,或者启用irqbalance服务来自动绑定IRQ到CPU核心上。
IRQ Balance
Irqbalance是一个linux的实用程序,它主要是用于分发中断请求到CPU核心上,有助于性能的提升。它的目的是寻求省电和性能优化之间的平衡。你可以使用yum进行安装:
\# rpm -qa | grep irqbalance irqbalance-0.55-15.el5 \# yum search irqbalance \# yum install irqbalance.x86_64
启动irqbalance服务后,中断在CPU上的分布如下:
\# cat /proc/interrupts CPU0 CPU1 CPU2 CPU3 0: 950901695 0 0 0 IO-APIC-edge timer 1: 13 0 0 0 IO-APIC-edge i8042 6: 96 10989 470 0 IO-APIC-edge floppy 7: 0 0 0 0 IO-APIC-edge parport0 8: 1 0 0 0 IO-APIC-edge rtc 9: 0 0 0 0 IO-APIC-level acpi 12: 109 1787 0 0 IO-APIC-edge i8042 15: 99 84813914 0 0 IO-APIC-edge ide1 51: 17371 0 46689970 0 IO-APIC-level ioc0 67: 1741 0 0 225409160 PCI-MSI eth0 83: 0 0 0 0 PCI-MSI vmci NMI: 0 0 0 0 LOC: 950902917 950903742 950901202 950901400 ERR: 0 MIS: 0
Irqbalance对于包含多个核心的系统来说是非常有用的。因为通常中断只被第一个CPU核心服务。以上就是教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“Linux”,或扫描下方二维码进行关注,更多干货等着你 !
以上是Linux CPU 中斷:非同步事件與通用處理機制的詳細內容。更多資訊請關注PHP中文網其他相關文章!