陷阱、故障與中斷(a trap, a fault, and an interrupt)
想像你正在桌前讀書,有三種不同的事情可能把你的注意力拉到前面的辦公室。第一,你刻意按了櫃台的鈴,因為你需要協助——這是你選的。第二,你想打開一個抽屜,它卡住了,逼你停下來處理問題——這是你自己的動作出了錯而來的。第三,門鈴響了,因為外面來了一份送貨——和你正在做的事毫無關係。這三者正是陷阱、故障與中斷在日常裡的樣貌:三者都把 CPU 拉進核心,但原因非常不同。
以下是精確的區別。陷阱(trap)是同步且刻意的:程式刻意執行一條指令(如 syscall 指令)來請核心提供服務。故障(fault)是同步但非刻意的:CPU 正在執行一條指令時偵測到某處不對——除以零、解參考一個無效位址、碰到一個不在記憶體裡的分頁——於是切到核心來處理;有些故障是可復原的(核心載入缺少的分頁,再重新執行那條指令),有些則是致命的(它以記憶體區段錯誤殺掉程式)。中斷(interrupt)是非同步且外部的:像網路卡、磁碟、鍵盤、或計時器這類裝置發出一個信號,與當下正在執行的指令毫無關係;CPU 暫停、跳到核心的處理常式、服務該裝置、再繼續。分界線是:同步(由當前指令引起)相對於非同步(由外部裝置引起)、以及刻意(陷阱)相對於非刻意(故障)。這三者合起來就是核心的進入點。
為何重要:把這三者分清楚,是讀懂核心究竟如何取得控制權的關鍵。系統呼叫是陷阱;記憶體區段錯誤與分頁錯誤是故障;按一個鍵或抵達一個網路封包是中斷。人們常籠統地把它們一律歸為「例外」、甚至全叫「中斷」,但這三者在成因上、以及能否重試上都不同。知道哪個是哪個,就能告訴你一個事件是程式自己造成的、是個錯誤、還是外界在敲門。
呼叫 write() 是陷阱——你主動要求的。解參考一個 NULL 指標觸發故障——CPU 抓到你的錯誤存取。完成的磁碟讀取或按下的一個鍵引發中斷——外界抵達了,與你程式當下所在的指令無關。
陷阱=你主動要求;故障=你的指令出了錯;中斷=外界抵達。
確切的術語因 CPU 與教科書而異——有些把陷阱與故障合稱為「例外(exceptions)」,各架構的命名也不同。要牢牢記住的、持久的區別是那兩個軸:同步相對於非同步、以及刻意相對於錯誤。