轉載請說明出處:http://blog.csdn.net/cywosp/article/details/26469435git
#include <pthread.h> // Returns 0 on success, or a positive error number on error int pthread_once (pthread_once_t *once_control, void (*init) (void)); 利用參數once_control的狀態,函數pthread_once()能夠確保不管有多少個線程調用多少次該函數,也只會執行一次由init所指向的由調用者定義的函數。init所指向的函數沒有任何參數,形式以下: void init (void) { // some variables initializtion in here }
另外,參數once_control必須是pthread_once_t類型變量的指針,指向初始化爲PTHRAD_ONCE_INIT的靜態變量。在C++0x之後提供了相似功能的函數std::call_once (),用法與該函數相似。使用實例請參考https://github.com/ApusApp/Swift/blob/master/swift/base/singleton.hpp實現。github
#include <pthread.h> // Returns 0 on success, or a positive error number on error int pthread_key_create (pthread_key_t *key, void (*destructor)(void *)); // Returns 0 on success, or a positive error number on error int pthread_key_delete (pthread_key_t key); // Returns 0 on success, or a positive error number on error int pthread_setspecific (pthread_key_t key, const void *value); // Returns pointer, or NULL if no thread-specific data is associated with key void *pthread_getspecific (pthread_key_t key);
void Dest (void *value) { // Release storage pointed to by 'value' }
因爲系統對每一個進程中pthread_key_t類型的個數是有限制的,因此進程中並不能建立無限個的pthread_key_t變量。Linux中能夠經過PTHREAD_KEY_MAX(定義於limits.h文件中)或者系統調用sysconf(_SC_THREAD_KEYS_MAX)來肯定當前系統最多支持多少個鍵。Linux中默認是1024個鍵,這對於大多數程序來講已經足夠了。若是一個線程中有多個線程局部存儲變量,一般能夠將這些變量封裝到一個數據結構中,而後使封裝後的數據結構與一個線程局部變量相關聯,這樣就能減小對鍵值的使用。
參數value的值也能夠不是一個指向調用者分配的內存區域,而是任何能夠強制轉換爲void*的變量值,在這種狀況下,先前的pthread_key_create()函數應將參數destructor設置爲NULL
pthread_key_create()返回的pthread_key_t類型值只是對全局數組的索引,該全局數組標記爲pthread_keys,其格式大概以下:
數組的每一個元素都是一個包含兩個字段的結構,第一個字段標記該數組元素是否在用,第二個字段用於存放針對此鍵、線程局部存儲變的解構函數的一個副本,即destructor函數。
__thread std::string t_object_1 ("Swift"); // 錯誤,由於不能調用對象的構造函數 __thread std::string* t_object_2 = new std::string (); // 錯誤,初始化必須用編譯期常量 __thread std::string* t_object_3 = nullptr; // 正確,可是須要手工初始化並銷燬對象