示例:
// 可重入函式
int double(int a)
// 不可重入函式
void foo()
對於函式中使用的某乙個變數,若兩次呼叫該函式時,這個變數都執行相同的結果,說明該函式是可重入的,否則是不可重入的。
從經驗上來講就是:如果函式中使用了全域性變數或者靜態變數,則該函式是不可重入的,否則是可重入的。
下面給乙個例子來說明不可重入函式。
#include #include #include int g_v[10];//全域性變數
int *h_v;//堆中的資料
void set(int val)
printf("g_v:");
for(i = 0; i < 10; ++i)
printf("\n");
printf("h_v:");
for(i = 0; i < 10; ++i)
printf("\n");
printf("a_v:");
for(i = 0; i < 10; ++i)
printf("\n");
}void sig_handler(int signo)
}int main(void)
上述**中定義了兩個全域性變數g_v和h_v,還在set函式中定義了乙個區域性變數a_v,在set函式中給這三個陣列賦值。
如果過程中沒有發生訊號,則**執行結果如下:
如果在執行set給三個變數賦值的過程中產生了乙個sigtstp訊號,則程式轉到訊號處理函式中,並第二次執行set函式。
由於a_v屬於棧中資料,所以每次執行都會重新分配乙個棧空間。而g_v和h_v分別屬於資料段空間和堆空間,所以在整個程式執行過程中只開闢一段記憶體空間。根據執行結果可以分析出,第一次執行set時,當i=1執行完,即第二次賦值完成後產生了乙個sigtstp訊號。於是執行第一次set函式中斷,稍後接著第二次執行set函式,所以第一次輸出全部為20。這時轉到第一次中斷處繼續執行,因為第一次執行到i=1處中斷,所以從i=2接著繼續賦值。第乙個棧中的a_v前兩個已經賦值為10,所以這裡接著賦值10,最後全部為10。而g_v和h_v現在全部為20,但是此時要從中斷處即i=2處繼續賦值,所以前兩個為20保持不變,後面的依然賦值為10,所以就得到了下面的結果。
函式的可重入性(Reentrancy)
什麼是可重入?可重入函式是乙個可以被多個任務呼叫的過程,任務在呼叫時不必擔心資料是否會出錯。在寫函式時只要考慮到盡量用區域性變數 例如暫存器 堆疊中的變數 對於要使用的全域性變數要加以保護 例如採用關中斷 訊號量等 這樣構成的函式就一定是乙個可重入的函式。此外,編譯器是否有可重入函式的庫,與它所服務...
訊號之函式的可重入性
訊號之函式的可重入性 在呼叫某個函式過程 現中斷訊號,且改訊號處理函式中再次呼叫該函式,訪問全域性 靜態變數的函式是不可重入函式。前後資料不一致,函式是不可重入的,特點 函式中使用全域性變數或靜態變數。前後資料一致,函式是可重入的,特徵 函式中使用區域性變數。root spark cat reins...
可重入函式 可重入核心
可重入函式這一概念早有接觸,但一直未有系統的理解,最近閱讀 apue 訊號一章時,其中講解很到位,故總結如下。訊號作為一種軟中斷,能夠被程序給捕獲,因而也就中斷程序的正常執行,轉而去執行訊號處理程式,最後再返回到原程序繼續正常執行。然而,當程序正在執行 malloc 動態記憶體分配時,訊號產生從而轉...