執行緒區域性儲存tls的使用

2022-05-23 14:06:14 字數 2327 閱讀 3443

執行緒區域性儲存(thread local storage,tls)主要用於在多執行緒中,儲存和維護一些執行緒相關的資料,儲存的資料會被關聯到當前執行緒中去,並不需要鎖來維護。。

因此也沒有多執行緒間資源競爭問題,那如何去實現tls儲存呢,主要有以下幾種方式:

gcc和clang的__thread修飾符

windows下msvc的__declspec(thread)修飾符

pthread庫pthread_setspecificpthread_getspecific介面

windows下的tlssetvaluetlsgetvalue

__thread和__declspec(thread)的使用

例如:

tb_void_t tb_thread_func(tb_cpointer_t priv)

如果執行多個執行緒的話,上述**中每個執行緒的變數a的值,都是不相同的,值為每個執行緒的id

__declspec(thread)用起來也是類似,只需替換下__thread就行了

雖然這兩個修飾符用起來很方便,但是需要編譯器支援,雖然現在大部分平台的編譯器都已支援,但是作為跨平台開發,這樣還是不夠的

畢竟還是有不少低版本gcc,不一定支援__thread,尤其是嵌入式開發領域,交叉編譯工具鏈中的編譯器支援力度差異還是蠻大的。。

另外,使用__thread進行tls資料維護,需要手動管理相關記憶體的釋放問題,用的不好很容易導致記憶體洩露。。

pthread介面

我們看個簡單的例子:

// 測試執行緒中tls變數儲存的key,需定義為全域性或者static

static pthread_key_t g_local_key = 0;

static tb_void_t tb_thread_local_free(tb_pointer_t priv)

static tb_void_t tb_thread_local_init(tb_void_t)

static tb_int_t tb_thread_local_test(tb_cpointer_t priv)

return

0;}

tlssetvalue 介面
static tb_int_t tb_thread_local_test(tb_cpointer_t priv)

return

0;}

其實windows上還提供了flsalloc, flssetvalue系列介面,給協程使用,並且支援註冊自動釋放的**函式,不過對系統版本有些要求,像xp這些老系統就用不了了。。

這裡就不多描述了。

tbox提供的thread_local介面封裝

最近對tbox的tls介面進行了改造,並且重構了實現邏輯,在剪口易用性、功能性以及效率上都得到了很大的提公升。。

目前支援以下功能:

tbox退出時會自動銷毀所有建立的key,當然也可以提前主動銷毀它

用起來也很方便,很pthread很類似,但是內部自動呼叫了pthread_once,不用想pthread那樣顯式的去呼叫它了,例如:

static tb_void_t tb_demo_thread_local_free(tb_cpointer_t priv)

static tb_int_t tb_demo_thread_local_test(tb_cpointer_t priv)

return

0;}

當然你可以可以主動呼叫:tb_thread_local_exit(&s_local)來銷毀它。。

tbox的這套介面,相比pthread減少了乙個init的**函式,比windows那套多了自動釋放的機制,並且同時支援跨平台。。

雜談之前我看到一些庫中,對__thread和pthread介面進行了混用,感到很是莫名,個人感覺是有問題的,例如:

static __thread pthread_key_t g_key;
原本pthread文件中就明確表述key需要全域性或者static儲存,而這裡加上__thread後,其實每個執行緒訪問的key都不是同乙個key了哦。。

總結如果要考慮跨平台操作的話,tbox的tls介面也是個不錯的選擇哦。。

個人主頁:tboox開源工程

原文出處:

執行緒區域性儲存(TLS)的使用

將執行緒的私有資料 區域性儲存的資料 共享,以供本程序中的其它執行緒使用。l 適用情形 執行緒區域性儲存適用於多執行緒共享資料,而又不需要同步的情形。執行緒同步的開支比較大。l 原理 在每個執行緒中有乙個儲存區域,該儲存區域有64個slot 資料槽 可以通過該slot的索引值 乙個dword數值 獲...

執行緒區域性儲存 TLS

本來想通過tid為索引建個表來實現該功能,沒想到已經有現成的機制。單個執行緒的特有資料,介於全域性變數和區域性變數之間。linux 方法一 int pthread key create pthread key t key,void destructor void int pthread key de...

TLS執行緒區域性儲存

為執行緒單獨提供的私有空間 隱式tls thread int number 顯式tls pthread key create pthread getspecific pthread setspecific pthread key delete 隱式tls declspec thread int nu...