壹。數據類型
C/C++程序中經常有全局變量、函數中定義的靜態變量和局部變量。對於局部變量,不存在線程安全問題,因此超出了本文的討論範圍。函數中定義的全局變量和靜態變量是* * *共享變量,所有線程都可以在同壹個進程中訪問這些變量,因此它們存在多線程讀寫的問題。當壹個線程修改壹個變量的內容時,其他線程可以感知和讀取更改的內容,這對於數據交換來說非常快。但是,由於多線程的存在,可能會有兩個或多個線程同時為同壹個變量修改變量所在內存的內容,同時也可能會有多個線程在修改變量時讀取內存值。如果不使用相應的同步機制來保護存儲器,則讀取的數據將是不可預測的,甚至是可能的。
如果我們需要壹個線程內的所有函數調用都可以訪問但其他線程不能訪問的變量,我們需要壹種新的機制來實現它,這種機制稱為線程本地靜態內存,也可以稱為線程特定數據(TSD)或線程本地存儲(TLS)。這種類型的數據,在程序中,每個線程都會維護壹個變量的副本,並且它會長期存在於這個線程中,並且這種變量的操作不會影響其他線程。如下圖所示:
第二,壹次性初始化
在解釋特定於線程的數據之前,我們先來看看壹次性初始化。多線程程序有時要求無論創建多少個線程,有些數據只能初始化壹次。例如,在C++程序中,壹個類在整個進程生命周期中只能有壹個實例對象。在多線程的情況下,為了能夠安全地初始化對象,壹次性初始化機制尤為重要。-在設計模式中,這種實現通常稱為單例模式。Linux中提供了以下函數來實現壹次性初始化:
# include & ltpthread.h & gt
//成功時返回0,出錯時返回正錯誤號
int pthread _ once(pthread _ once _ t * once _ control,void(* init)(void));
使用參數once_control的狀態,函數pthread_once()可以確保無論有多少個線程調用該函數,由init指向的調用者定義的函數都只會執行壹次。init指向的函數沒有參數,形式如下:
無效初始化(無效)
{
//壹些變量在這裏初始化
}
此外,參數once_control必須是指向pthread_once_t類型變量的指針,指向初始化為PTHRAD_ONCE_INIT的靜態變量。C++0x之後提供了功能類似的函數std::call_once(),其用法與此函數類似。請參考/apus app/swift/blob/master/swift/base/singleton . HPP中的示例。