函式的可重入性

2021-07-25 07:47:50 字數 1377 閱讀 7852

示例:

// 可重入函式

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 動態記憶體分配時,訊號產生從而轉...