可重入函數與線程安全

線程安全函數 
概念: 
       線程安全的概念比較直觀。一般說來,一個函數被稱爲線程安全的,當且僅當被多個併發線程反覆調用時,它會一直產生正確的結果。 線程安全指的是多線程併發執行時,能夠得到正確的結果,這裏強調的是併發性,確保線程安全的措施是:線程安全函數不使用共享數據(全局、靜態或堆)或者對共享數據實施同步機制保護。
確保線程安全: 
       要確保函數線程安全,主要需要考慮的是線程之間的共享變量。屬於同一進程的不同線程會共享進程內存空間中的全局區和堆,而私有的線程空間則主要包括棧和寄存器。因此,對於同一進程的不同線程來說,每個線程的局部變量都是私有的,而全局變量、局部靜態變量、分配於堆的變量都是共享的。在對這些共享變量進行訪 問時,如果要保證線程安全,則必須通過加鎖的方式。


可重入函數 
概念:

可重入函數主要用於多任務環境中,一個可重入的函數簡單來說就是可以被中斷的函數,也就是說,可以在這個函數執行的任何時刻中斷它,轉入OS調度下去執行另外一段代碼,而返回控制時不會出現什麼錯誤;而不可重入的函數由於使用了一些系統資源,比如全局變量區,中斷向量表等,所以它如果被中斷的話,可能會出現問題,這類函數是不能運行在多任務環境下的。

確保可重入: 
       要確保函數可重入,需滿足以下幾個條件: 
       1、不在函數內部使用靜態或全局數據 
       2、不返回靜態或全局數據,所有數據都由函數的調用者提供。 
       3、使用本地數據,或者通過製作全局數據的本地拷貝來保護全局數據。 
       4、不調用不可重入函數。 

不可重入的後果: 
       不可重入的後果主要體現在象信號處理函數這樣需要重入的情況中。如果信號處理函數中使用了不可重入的函數,則可能導致程序的錯誤甚至崩潰。


可重入函數與線程安全:

可重入與線程安全並不等同。一般說來,可重入的函數一定是線程安全的,但反過來不一定成立。

  例如:

      - 如果一個函數中用到了全局或靜態變量,那麼它不是線程安全的,也不是可重入的; 
     - 如果我們對它加以改進,在訪問全局或靜態變量時使用互斥量或信號量等方式加鎖,則可以使它變成線程安全的,但此時它仍然是不可重入的,因爲通常加鎖方式是針對不同線程的訪問,而對同一線程可能出現問題;
      - 如果將函數中的全局或靜態變量去掉,改成函數參數等其他形式,則有可能使函數變成既線程安全,又可重入。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章