2011-06-30 140 views
4

我讀的C++設計與演變,由Bjarne Stroustrup的。關於異常處理和異步信號,提及如下:C++異常和信號處理程序

是否可以使用異常來處理信號?幾乎肯定不是在大多數C環境中。麻煩的是C使用了像malloc這樣的函數,這些函數不可重入。如果在malloc中間發生中斷並導致異常,則無法阻止異常處理程序再次執行malloc。

A C++實現,其中調用序列,並在整個運行時庫是圍繞重入的要求設計將有可能使信號扔exceptoins

是什麼筆者通過的聲明「是什麼意思沒有辦法阻止異常處理程序再次執行malloc「?如何使函數重入可以拋出信號處理程序的異常?

回答

4

在我看來,這部分對當前的C++沒有多大意義。

在C++中沒有辦法來使用異常作爲信號,因爲信號被意味着要執行的處理程序,然後(可能)繼續執行。

但是,C++異常不能以這種方式工作。一旦你到達了異常處理程序,堆棧已經被回滾,並且在處理之後沒有辦法「繼續」:沒有辦法在throw之後到達語句(或者在函數調用之後得到異常拋出)。

信號是異步的,但不是破壞性的,並且在信號有可能發生後繼續進行(即使必須注意信號處理程序中所做的事情),例外情況會破壞程序流程,並且繼續是不可能的。

我想說這兩個想法在邏輯層面上是不兼容的,如果圖書館是可重入的,這並不重要。

可能是在C++早期設計有例外的恢復選項...

+0

這是偉大的,你指出了執行程序無法繼續拋出異常後未捕獲的是。 – Leviathlon

3

如果例如調用malloc的感應信號,然後如果你把從信號處理程序的malloc異常可以由異常拋出邏輯再次調用。由於malloc不是可重入的,因此你會以未定義的行爲結束。

一個處理信號的方法是隻需按下一個信號事件到你的事件隊列,並從信號處理程序立即返回。然後,當事件循環處理信號事件時,它可以做任何想做的事情,因爲它不在信號處理程序的限制範圍內。

1

一個功能是「重入」,如果它能夠在執行過程中被中斷,並且中斷調用完成之前再次調用。查看它的另一種方法:可以從信號處理程序中調用可重入函數。所有的投注都是在信號處理程序中調用非重入函數。應該從信號處理程序中調用的唯一函數是那些已知可重入的函數。

malloc不可重入。如果malloc進入kaboom,則無法告訴kaboom是否正在更新任何全局數據malloc在幕後使用以跟蹤分配的數據。

與信號處理程序相對於異常的另一個問題:代碼在一個信號處理程序執行基本上在不同的線程比主代碼運行。 如果信號可以被尋址,信號處理程序的返回信號返回到剛剛發生信號的點之後。你打算如何在信號處理程序中拋出異常?做到這一點,信號處理程序不再返回!這意味着執行的其餘部分是從信號處理程序中有效完成的。現在發生另一個信號時會發生什麼?這兩個概念不會混合。重入不過是這裏的冰山一角。