對比執行緒安全和可重入函式
阿新 • • 發佈:2018-12-31
1.什麼叫執行緒安全
如果你的程式所在的程序中有多個執行緒在同時執行,而這些執行緒可能同時執行一段程式碼或同時訪問一個物件,如果每次執行完這段程式碼或訪問完這個物件之後,所得到的結果和單執行緒執行的結果一樣,而其他變數的值也和預期的保持一致,那麼就認為是執行緒安全的。也就是說當多個執行緒同時運行同一段程式碼,不會造成資源的衝突,不會產生錯誤的結果就是執行緒安全的。如果有一段執行緒安全的程式碼(原子操作或執行緒間切換不會導致結果的二義性),它在多個執行緒中使用是不需要作同步處理的;而執行緒不安全的程式碼在多執行緒環境中必須作同步處理,否則會造成不可不可預期的後果。
2.不可重入性和可重入性
3.可重入函式
(1)不在函式內部使用靜態或全域性資料 (2)不返回指向靜態資料的指標,所有資料都由函式呼叫者來提供 (3)使用本地資料,或通過製作全域性資料的本地拷貝來保護全域性資料 (4)如果必須訪問全域性變數,利用互斥機制來保護全域性變數 (5)不呼叫不可重入函式4.不可重入函式
(1)函式中使用了靜態變數,不論全域性或者區域性靜態變數5.執行緒不安全函式的分類
(1)不保護共享變數的函式採用加鎖即可。
(2)保持跨越多個呼叫的狀態函式。如rand庫函式,這種情況下要麼重寫它,使它不包含任何靜態資料,依靠呼叫者在引數中傳遞引數資訊;或者採用庫函式提供的可重入版本,而可重入版本的函式名是在原函式名尾部加上_r,即為rand_r。 (3)返回指向靜態變數指標的函式。如gethostbyname函式struct hostent* gethostbyname_ts(char* host)
{
struct hostent* shared, * unsharedp;
unsharedp = Malloc(sizeof(struct hostent));
P(&mutex)
shared = gethostbyname(hostname);
*unsharedp = * shared;
V(&mutex);
return unsharedp;
}
(4)呼叫了執行緒不安全函式的函式。