可重入函式(reentrant function)與執行緒安全函式(thread-safe function)有時容易混淆,而且各種文件中的解釋也不是很清楚,這裡根據筆者的經驗來說明一下。
執行緒安全函式
·概念:
執行緒安全的概念比較直觀。一般說來,乙個函式被稱為執行緒安全的,當且僅當被多個併發執行緒反覆呼叫時,它會一直產生正確的結果。
·確保執行緒安全:
要確保函式執行緒安全,主要需要考慮的是執行緒之間的共享變數。屬於同一程序的不同執行緒會共享程序記憶體空間中的全域性區和堆,而私有的執行緒空間則主要包括棧和暫存器。因此,對於同一程序的不同執行緒來說,每個執行緒的區域性變數都是私有的,而全域性變數、區域性靜態變數、分配於堆的變數都是共享的。在對這些共享變數進行訪問時,如果要保證執行緒安全,則必須通過加鎖的方式。
·執行緒不安全的後果:
執行緒不安全可能導致的後果是顯而易見的——共享變數的值由於不同執行緒的訪問,可能發生不可預料的變化,進而導致程式的錯誤,甚至崩潰。
可重入函式
·概念:
可重入的概念基本沒有比較正式的完整解釋,多數的文件都只是說明什麼樣的情況才能保證函式可重入,但沒有完整定義。按照wiki上的說法,「a computer program or routine is described asreentrantif it can be safely executedconcurrently; that is, the routine can be re-entered while it is already running.」根據筆者的經驗,所謂「重入」,常見的情況是,程式執行到某個函式foo()時,收到訊號,於是暫停目前正在執行的函式,轉到訊號處理函式,而這個訊號處理函式的執行過程中,又恰恰也會進入到剛剛執行的函式foo(),這樣便發生了所謂的重入。此時如果foo()能夠正確的執行,而且處理完成後,之前暫停的foo()也能夠正確執行,則說明它是可重入的。
·確保可重入:
要確保函式可重入,需滿足一下幾個條件:
1、不在函式內部使用靜態或全域性資料
2、不返回靜態或全域性資料,所有資料都由函式的呼叫者提供。
3、使用本地資料,或者通過製作全域性資料的本地拷貝來保護全域性資料。
4、不呼叫不可重入函式。
·不可重入的後果:
不可重入的後果主要體現在象訊號處理函式這樣需要重入的情況中。如果訊號處理函式中使用了不可重入的函式,則可能導致程式的錯誤甚至崩潰。
可重入與執行緒安全
可重入與執行緒安全並不等同,一般說來,可重入的函式一定是執行緒安全的,但反過來不一定成立。它們的關係可用下圖來表示:
比如:strtok函式是既不可重入的,也不是執行緒安全的;加鎖的strtok不是可重入的,但執行緒安全;而strtok_r既是可重入的,也是執行緒安全的。
可重入函式與執行緒安全
執行緒安全 乙個函式被稱為執行緒安全的 thread safe 當且僅當被多個併發程序反覆呼叫時,它會一直產生正確的結果。如果乙個函式不是執行緒安全的,我們就說它是執行緒不安全的 thread unsafe 我們定義四類 有相交的 執行緒不安全函式。將這類執行緒不安全函式變為執行緒安全的,相對比較容...
可重入函式與執行緒安全
可重入函式與執行緒安全 執行緒安全 假如在乙個函式中它是這麼寫的,在乙個全域性鍊錶上存放資料,在單執行緒模式下,我們先new乙個新的節點然後讓head next指向這個節點,這種場景在多執行緒場景下會是這樣的過程,執行緒一new了乙個節點,然後cpu轉去執行執行緒二,執行緒二new乙個節點後head...
可重入函式與執行緒安全
若乙個程式或子程式可以 安全的被並行執行 parallel computing 則稱其為可重入 reentrant或re entrant 的。即當該子程式正在執行時,可以再次進入並執行它 並行執行時,個別的執行結果,都符合設計時的預期 可重入概念是在單執行緒作業系統的時代提出的。乙個子程式的重入,可...