可重入和不可重入

2022-05-28 06:21:09 字數 1035 閱讀 2324

這種情況出現在多工系統當中,在任務執行期間捕捉到訊號並對其進行處理時,程序正在執行的指令序列就被訊號處理程式臨時中斷。如果從訊號處理程式返回,則繼續執行程序斷點處的正常指令序列,從重新恢復到斷點重新執行的過程中,函式所依賴的環境沒有發生改變,就說這個函式是可重入的,反之就是不可重入的。

眾所周知,在程序中斷期間,系統會儲存和恢復程序的上下文,然而恢復的上下文僅限於返回位址,cpu暫存器等之類的少量上下文,而函式內部使用的諸如全域性或靜態變數,buffer等並不在保護之列,所以如果這些值在函式被中斷期間發生了改變,那麼當函式回到斷點繼續執行時,其結果就不可預料了。打個比方,比如malloc,將如乙個程序此時正在執行malloc分配堆空間,此時程式捕捉到訊號發生中斷,執行訊號處理程式中恰好也有乙個malloc,這樣就會對程序的環境造成破壞,因為malloc通常為它所分配的儲存區維護乙個鏈結表,插入執行訊號處理函式時,程序可能正在對這張表進行操作,而訊號處理函式的呼叫剛好覆蓋了程序的操作,造成錯誤。

滿足下面條件之一的多數是不可重入函式:

(1)使用了靜態資料結構;

(2)呼叫了malloc或free;

(3)呼叫了標準i/o函式;標準io庫很多實現都以不可重入的方式使用全域性資料結構。

(4)進行了浮點運算.許多的處理器/編譯器中,浮點一般都是不可重入的 (浮點運算大多使用協處理器或者軟體模擬來實現。

1) 訊號處理程式a內外都呼叫了同乙個不可重入函式b;b在執行期間被訊號打斷,進入a (a中呼叫了b),完事之後返回b被中斷點繼續執行,這時b函式的環境可能改變,其結果就不可預料了。

2) 多執行緒共享程序內部的資源,如果兩個執行緒a,b呼叫同乙個不可重入函式f,a執行緒進入f後,執行緒排程,切換到b,b也執行了f,那麼當再次切換到執行緒a時,其呼叫f的結果也是不可預料的。

在訊號處理程式中即使呼叫可重入函式也有問題要注意。作為乙個通用的規則,當在訊號處理程式中呼叫可重入函式時,應當在其前儲存errno,並在其後恢復errno。(因為每個執行緒只有乙個errno變數,訊號處理函式可能會修改其值,要了解經常**捉到的訊號是sigchld,其訊號處理程式通常要呼叫一種wait函式,而各種wait函式都能改變errno。)

可重入和不可重入

重入一般可以理解為乙個函式在同時多次呼叫,例如作業系統在程序排程過程中,或者微控制器 處理器等的中斷的時候會發生重入的現象。一般浮點運算都是由專門的硬體來完成,舉個例子假設有個硬體暫存器名字叫做float,用來計算和存放浮點數的中間運算結果 假設有這麼個函式 void fun 假如第一次執行,有個對...

可重入和不可重入

重入一般可以理解為乙個函式在同時多次呼叫,例如作業系統在程序排程過程中,或者微控制器 處理器等的中斷的時候會發生重入的現象。一般浮點運算都是由專門的硬體來完成,舉個例子假設有個硬體暫存器名字叫做float,用來計算和存放浮點數的中間運算結果 假設有這麼個函式 void fun 假如第一次執行,有個對...

可重入和不可重入

重入一般可以理解為乙個函式在同時多次呼叫,例如作業系統在程序排程過程中,或者微控制器 處理器等的中斷的時候會發生重入的現象。一般浮點運算都是由專門的硬體來完成,舉個例子假設有個硬體暫存器名字叫做float,用來計算和存放浮點數的中間運算結果 假設有這麼個函式 void fun 假如第一次執行,有個對...