信號(signal)和異常(exception)存在哪些異同?
01-04
- signal:指軟中斷信號
- exception:可以打破主事件流的機制,例如 C++ 的異常
提出這個問題是因為發現二者有相似之處,都可以改變原本的主事件流。更有在 Python 等語言實現中,異常是被當成信號通知機制來使用的(例如 StopIteration)。
既然提問者已經補充了一些信息,那麼我的定義和理解是以下這些:
- 信號 / signal:軟體中斷,特指由操作系統發出給應用的非同步提示機制,如 Unix signal 。除零錯誤等 CPU 信號最終仍然被表現為 SIGFPE 信號,否則不在此討論(如 IRQ 中斷等)
- 異常:按照提問者的補充,為編程語言或環境提供的、同步的錯誤提示方法,如 C++ / Java 中 throw 的、Python 中 raise 出的對象
Windows 的 SEH(Structured Exception Handling,http://msdn.microsoft.com/en-us/library/windows/desktop/ms680657(v=vs.85).aspx)同時包含了以上兩種情況,不討論。
那麼兩者的區別已經很明顯了:- 信號由操作系統發出,更為底層,與程序的執行是非同步的,由特殊的處理函數進行非同步處理(signal / signaction),與程序語言之間幾乎沒有集成,處理難度更大。
- (編程語言)異常則由程序語言和運行時提供,是一種可控的、同步激發處理、被語言和運行時支持的、可進行結構化處理的流程式控制制機制(與 return 和 if else for while 等沒有本質區別)。
總的來說,後者處理過程由於是語言直接支持的,難度較小,資源管理較容易,是一種比較「高級」的機制。後者是可以基於前者實現(也可以完全無關)。
除非環境明確要求,一般的程序流程式控制制只涉及後者;如果環境支持,可能會將 OS 發出的信號包裝成對應的異常交給應用處理。注意:本解答是在提問者補充提問前給出的。
兩者是不同層面上的概念,無法比較。Signal 是軟體上的概念,指的是由 Kernel 產生,並由用戶態程序響應的事件。Exception 是硬體上的概念,指的是 CPU 因執行某些指令而產生的事件,比如常見的除零錯誤。另外,相對於 Interrupt,Exception 是同步的,Interrupt 是非同步的;Exception 是由執行指令產生的,Interrupt 則是由硬體產生的。正在看這部分的內容,做回搬運工:
Unix signal
簡而言之就是,對於操作系統可以處理的Exception,kernel會自己處理,這裡舉得例子是page fault,類比來看I/O interupt應該也屬於這種。kernel沒有足夠信息來處理的Exception就會使用signal機制。推薦閱讀:
※你的Linux系統是否經常更新呢?
※vim只能在linux下才能得到最好的體驗嗎?
※龔神給微軟 Linux 子系統寫的支持 DirectX 9、11的代碼到底屬不屬於「驅動」?
※有哪些靠譜的 Ubuntu 使用教材?