歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> Linux技術

Linux中的線程局部存儲(二)

轉載請說明出處:/content/6643581.html
在Linux中還有一種更為高效的線程局部存儲方法,就是使用關鍵字__thread來定義變量。__thread是GCC內置的線程局部存儲設施(Thread-Local
Storage),它的實現非常高效,與pthread_key_t向比較更為快速,其存儲性能可以與全局變量相媲美,而且使用方式也更為簡單。創建線程局部變量只需簡單的在全局或者靜態變量的聲明中加入__thread說明即可。列如:
static __thread char t_buf[32]
= {'\0'};
extern __thread int t_val
= 0;
凡是帶有__thread的變量,每個線程都擁有該變量的一份拷貝,且互不干擾。線程局部存儲中的變量將一直存在,直至線程終止,當線程終止時會自動釋放這一存儲。__thread並不是所有數據類型都可以使用的,因為其只支持POD(Plain
old data structure)[1]類型,不支持class類型——其不能自動調用構造函數和析構函數。同時__thread可以用於修飾全局變量、函數內的靜態變量,但是不能用於修飾函數的局部變量或者class的普通成員變量。另外,__thread變量的初始化只能用編譯期常量,例如:
__thread std::string t_object_1 ("Swift");
// 錯誤,因為不能調用對象的構造函數
__thread std::string* t_object_2 = new std::string
(); // 錯誤,初始化必須用編譯期常量
__thread std::string* t_object_3 = nullptr;
// 正確,但是需要手工初始化並銷毀對象
除了以上之外,關於線程局部存儲變量的聲明和使用還需注意一下幾點:
如果變量聲明中使用量關鍵字static或者extern,那麼關鍵字__thread必須緊隨其後。
與一般的全局變量或靜態變量一樣,線程局部變量在聲明時可以設置一個初始化值。
可以使用C語言取地址符(&)來獲取線程局部變量的地址。
__thread的使用例子可參考https://github.com/ApusApp/Swift/blob/master/swift/base/logging.cpp的實現及其單元測試對於那些非POD數據類型,如果想使用線程局部存儲機制,可以使用對pthread_key_t封裝的類來處理,具體方式可參考https://github.com/ApusApp/Swift/blob/master/swift/base/threadlocal.h的實現以及其的單元測試。
參考
[1]http://zh.wikipedia.org/wiki/POD_(%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1) [2] Linux/UNIX系統編程手冊(上)
[3] Linux多線程服務端編程使用muduo C++網絡庫
Copyright © Linux教程網 All Rights Reserved