可重入函數和線程安全的區別與聯繫

什麼是線程安全:一個函數被稱爲線程安全的(thread-safe),當且僅當被多個併發進程反覆調用時,它會一直產生正確的結果。反之,如果一個函數不是線程安全的,我們就說它是線程不安全的(thread-unsafe)。

所以,有這麼四類函數稱爲線程不安全的:

  1. 不保護共享變量的函數;
  2. 函數狀態隨着調用改變的函數;
  3. 返回指向靜態變量指針的函數;
  4. 調用線程不安全函數的函數

什麼是可重入函數:可重入函數是線程安全函數的一種,其特點在於它們被多個線程調用時,不會引用任何共享數據。函數是可重入reentrant)的,是指對於相同的(並且合法的)函數參數(包括無參函數的情況),多次調用此函數產生的行爲是可預期的,即函數的行爲一致,或者結果相同。不能保證這一點的函數稱爲不可重入(non-reentrant)函數。

它又分爲這麼兩種:

顯式可重入函數:如果所有函數的參數都是傳值傳遞的(沒有指針),並且所有的數據引用都是本地的自動棧變量(也就是說沒有引用靜態或全局變量),那麼函數就是顯示可重入的,也就是說不管如何調用,我們都可斷言它是可重入的。

隱式可重入函數:可重入函數中的一些參數是引用傳遞(使用了指針),也就是說,在調用線程小心地傳遞指向非共享數據的指針時,它纔是可重入的。

可見,可重入函數的可重入性是有時是調用者與被調用這共有的屬性,並不只是被調用者的屬性。

對比:

可重入和線程安全(Thread-Safe)是兩個不同的概念:可重入函數一定是線程安全的;線程安全的函數可能是重入的,也可能是不重入的;線程不安全的函數一定是不可重入的。
可重入函數要解決的問題是,不在函數內部使用靜態或全局數據,不返回靜態或全局數據,也不調用不可重入函數。

線程安全函數要解決的問題是,多個線程調用函數時訪問資源衝突。

函數如果使用靜態變量,通過加鎖後可以轉成線程安全函數,但仍然有可能不是可重入的。



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