可重入函式與執行緒安全

2021-08-18 11:33:50 字數 1376 閱讀 1958

在前面的學習中,我們已經介紹過了可重入函式,下面我們先來複習一些基本的概念:

(1)不在函式內部使用靜態或全域性資料;

(2)不返回靜態或全域性資料,所有資料都由函式的呼叫者提供;

(3)使用本地資料,或者通過製作全域性資料的本地拷貝來保護全域性資料;

(4)如果必須訪問全域性變數,利用互斥機制來保護全域性變數;

(5)不呼叫不可重入函式。

(1)函式中使用了靜態變數,無論是全域性靜態變數還是區域性靜態變數;

(2)函式返回靜態變數;

(3)函式中呼叫了不可重入函式;

(4)函式體內使用了靜態的資料結構;

(5)函式體內呼叫了malloc()或者free()函式;

(6)函式體內呼叫了其他標準i/o函式;

總的來說,如果乙個函式在重入條件下使用了未受保護的共享資源,那麼它是不可重入的。

(1)如果乙個函式當中有全域性變數,則該函式既不是執行緒安全的也不是可重入的;

(2)執行緒安全是在多執行緒情況下引發的,而可重入函式可以在只有乙個執行緒的情況下發生;

(3)執行緒安全不一定是可重入的,但可重入函式一定是執行緒安全的;

(4)如果對臨界資源的訪問加鎖,則這個函式是執行緒安全的;但如果重入函式加鎖還未釋放,則會產生死鎖,因此不能重入;

(5)執行緒安全函式能夠使不同的執行緒訪問同一塊位址空間,而可重入函式要求不同的執行流對資料的操作不影響結果,使結果是相同的。

示例:在多執行緒條件下,函式應當是執行緒安全的,進一步更強的條件是可重入的。可重入函式保證了在多執行緒條件下,函式的狀態不會出現錯誤。以下分別是乙個不可重入和可重入函式的示例:

static  int  tmp;

void func1(int *x,int *y)

void func2(int *x,int *y)

func1是不可重入的,func2是可重入的。因為在多執行緒條件下,作業系統會在func1還沒有執行完的情況下,切換到另乙個執行緒中,那個執行緒可能再次呼叫func1,這樣狀態就錯了。

**例項:

#include #includeint g_val = 0;

void fun()

} int main()

結果演示:

本**原本想實現最終g_val為3,結果在為2時,我們按下「ctrl+c」,產生了錯誤。由於變數是全域性的,收到2號訊號後,繼續進行+1運算,最終執行結果為6。因此該程式中,fun函式是不可重入函式。

為了防止這種情況的發生,我們可以將g_val改為區域性變數。這樣函式被二次呼叫時,兩次結果最終並不影響並且相等。

執行緒安全與可重入函式

可重入函式 reentrant function 與執行緒安全函式 thread safe function 有時容易混淆,而且各種文件中的解釋也不是很清楚,這裡根據筆者的經驗來說明一下。執行緒安全函式 概念 執行緒安全的概念比較直觀。一般說來,乙個函式被稱為執行緒安全的,當且僅當被多個併發執行緒反...

可重入函式與執行緒安全

執行緒安全 乙個函式被稱為執行緒安全的 thread safe 當且僅當被多個併發程序反覆呼叫時,它會一直產生正確的結果。如果乙個函式不是執行緒安全的,我們就說它是執行緒不安全的 thread unsafe 我們定義四類 有相交的 執行緒不安全函式。將這類執行緒不安全函式變為執行緒安全的,相對比較容...

可重入函式與執行緒安全

可重入函式與執行緒安全 執行緒安全 假如在乙個函式中它是這麼寫的,在乙個全域性鍊錶上存放資料,在單執行緒模式下,我們先new乙個新的節點然後讓head next指向這個節點,這種場景在多執行緒場景下會是這樣的過程,執行緒一new了乙個節點,然後cpu轉去執行執行緒二,執行緒二new乙個節點後head...