轉: 函數的線程安全和可重入

摘自:
http://liuaigui.blog.sohu.com/86494742.html

線程安全的(Thread-Safe):如果一個函數在同一時刻可以被多個線程安全地調用,就稱該函數是線程安全的。線程安全函數解決多個線程調用函數時訪問共享資源的衝突問題。

可重入(Reentrant):函數可以由多於一個線程併發使用,而不必擔心數據錯誤。可重入函數可以在任意時刻被中斷,稍後再繼續運行,不會丟失數據。可重入性解決函數運行結果的確定性和可重複性。可重入函數編寫規範爲:
1、不在函數內部使用靜態或全局數據 
2、不返回靜態或全局數據,所有數據都由函數的調用者提供。 
3、使用本地數據,或者通過製作全局數據的本地拷貝來保護全局數據。
4、如果必須訪問全局變量,利用互斥機制來保護全局變量。
5、不調用不可重入函數。

兩者之間的關係:
1、一個函數對於多個線程是可重入的,則這個函數是線程安全的。
2、一個函數是線程安全的,但並不一定是可重入的。
3、可重入性要強於線程安全性。

比如:strtok函數是既不可重入的,也不是線程安全的。加鎖的strtok不是可重入的,但線程安全。而strtok_r既是可重入的,也是線程安全的

之所以會去查這個問題,是在考試中遇到過考strtok這個問題是否可用於多線程。自己從使用的角度上感覺不安全,但是究其原因卻不是很明白。查了一下,居然涉及到函數的線程安全。

在另一篇博文中,是這樣解釋的:
strtok不是一個線程安全的函數。因爲根據其定義,它必須使用內部靜態變量來記錄字符串中下一個需要解析的標記的當前位置。但是,由於指示這個位置的變量只有一個,那麼,在同一個程序中出現多個解析不同字符串的strtok調用時,各自的字符串的解析就會互相干擾。(摘自: http://hi.baidu.com/pigfanfan/blog/item/72816c958d63e743d1135ebf.html

怎麼避免呢?
我們可以利用另一個函數:strtok_r,這個是一個線程安全的函數——strtok_r,以此來代替strtok。
發佈了72 篇原創文章 · 獲贊 10 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章