函式被不同的控制流程呼叫,有可能在第一次呼叫還沒返回時就再次 進入該函式,這稱為重入。
然而有可能因為重入而造成錯亂,像這樣 的函式稱為不可重入函式,
反之,如果乙個函式只訪問自己的區域性變數或引數,則稱為可重入 (reentrant) 函式。
可重入函式:
重入即表示重複進入,首先它意味著這個函式可以被中斷,其次意味著它除了使用自己棧上的變數以外不依賴於任何環境(包括static),這樣的函式就是purecode(純**)可重入,可以允許有多個該函式的副本在執行,由於它們使用的是分離的棧,所以不會互相干擾。如果確實需要訪問全域性變數(包括static),一定要注意實施互斥手段。可重入函式在並行執行環境中非常重要,但是一般要為訪問全域性變數付出一些效能代價。
滿足下列條件的函式多數是不可重入的:
1) 函式體內使用了靜態的資料結構;
2) 函式體內呼叫了malloc()或者free()函式;
3) 函式體內呼叫了標準i/o函式。
編寫可重入函式:
1、不能在函式內部使用靜態或全域性資料
2、不能返回靜態或全域性資料,所有資料都有函式的呼叫者提供
3、使用本地資料、或通過製作全域性資料的本地拷貝來保護全域性資料。
4、如果必須訪問全域性變數,利用互斥機制來保護全域性變數。
5、不在可重入函式內部呼叫不可重入函式。、
6、不呼叫malloc和free函式,因為malloc是用全域性鍊錶來管理堆的。
7、不呼叫了標準i/o函式。標準i/o函式很多都以不可重入的方式實現全域性資料結構。
注意:最常見的就是在訊號處理函式中不能使用不可重入函式。如果在訊號處理函式中使用了不可重入函式,則可能導致程式出現錯誤甚至崩潰。
執行緒當乙個函式被多個執行緒反覆呼叫的時候,他會一直產生正確的結果,那麼這個函式就是執行緒安全的。執行緒安全函式解決了多個執行緒呼叫函式時訪問臨界資源的衝突問題。
執行緒安全函式時,要注意兩點:
1, 減少對臨界資源的依賴,盡量避免訪問全域性變數,靜態變數或其它共享資源,如果必須要使用共享資源,所有使用到的地方必須要進行互斥鎖 (mutex) 保護;
2, 執行緒安全的函式所呼叫到的函式也應該是執行緒安全的,如果所呼叫的函式不是執行緒安全的,那麼這些函式也必須被互斥鎖 (mutex) 保護;
執行緒安全的根源就在於」共享資料」。所以不共享任何資料的函式(可重入函式)肯定是執行緒安全的。但是,即使有共享資料,執行緒安全還可以通過同步與互斥來保證,所以執行緒安全並不一定是可重入的。
對比執行緒安全和可重入函式
一 執行緒安全函式 1 什麼是執行緒安全 乙個函式被稱為執行緒安全,當且僅當它被多個併發的程序反覆呼叫時,它會一直產生正確的結果。反之,如果乙個函式不是執行緒安全的,我們就稱它是不安全的。執行緒安全主 要是針對資料競爭來說的,就是說,如果資料不需要共享,那就讓每個資料私有,如果需要共享,就得加鎖。2...
對比執行緒安全和可重入函式
1 執行緒安全 1 概念 執行緒安全的概念比較直觀。一般說來,乙個函式被稱為執行緒安全的,當且僅當被多個併發執行緒反覆呼叫時,它會一 直產生正確的結果。如果你的程式所在的程序中有 多個執行緒在同時執行 而這些執行緒可能 同時執行一段 或同時訪 問乙個物件 如果每次執行完這段 或訪問完這個物件之後,所...
執行緒安全和可重入函式
執行緒安全 當多個併發執行緒執行同乙個函式,我們都能得到正確的返回值。當多個執行緒併發的呼叫乙個函式。如果對全域性資料或者靜態資料在不加任何鎖以及安全性的處理情況下,就會對多次修改資料的錯誤。比如我正在願意個執行緒裡處理乙個全域性變數的 1 正減完。結果還沒有返回,就被另乙個執行緒切出去了,而那個執...