轉自:http://blog.csdn.net/kkxgx/article/details/7506085
版權聲明:本文為博主原創文章,未經博主允許不得轉載。
一,線程安全基礎
一個函數被稱為線程安全的當且僅當被多個並發線程反復調用時,它會一直產生正確的結果。我們能夠定義出四類線程不安全函數。
第一類:不保護共享變量的函數
共享變量在多線程中是共享數據,可以通過同步機制來保護共享數據。
第二類:保護跨越多個調用狀態的函數
一個偽隨機數生成器是一個簡單的例子:
- unsigned int next=1;
- int rand(void)
- {
- next=next*1103515245+12345;
- return (unsigned int )(next/65536)%32768;
- }
- void srand(unsigned int seed)
- {
- next=seed;
- }
rand函數是線程不安全的,因為當前調用的結果依賴於前次調用的中間結果。
第三類:返回指向靜態變量的指針的函數
某些函數(如gethostbyname)將計算結果放在靜態結構中,並返回一個指向這個結構的指針。在多線程中一個線程調用的結構可能被另一個線程覆蓋。可以通過重寫函數和加鎖拷貝技術來消除。加鎖拷貝技術指在每個位置對互斥鎖加鎖,調用線程不安全函數,動態的為結果分配存儲器,拷貝函數返回的結構,然后解鎖。
第四類:調用線程不安全函數
常見的系統線程不安全函數:
| 線程不安全函數 | 線程不安全 類 | unix線程安全版本 |
| rand | 2 | rand_r |
| strtok | 2 | strtok_r |
| asctime | 3 | asctime_r |
| ctime | 3 | ctime_r |
| gethostbyaddr | 3 | gethostbyaddr_r |
| geyhostbyname | 3 | gethostbyname_r |
| inet_ntoa | 3 | |
| localtime | 3 | localtime_r |
二、可重入性
有一類重要的線程安全函數,叫做可重入函數,其特點:當它們被多個線程調用時,不會引用任何共享數據。可重入、線程安全函數之間的關系如下圖。

