線程本地存儲(Thread Local Storage)


如果一個變量是全局的,那么所有線程訪問的是同一份,某一個線程對其修改會影響其他所有線程。如果我們需要一個變量在每個線程中都能訪問,並且值在每個線程中互不影響,這就是TLS。

 

線程局部存儲在不同平台有不同的實現,可移植性不好。線程局部存儲不難實現,最簡單的辦法是建立一個全局表,通過當前線程ID去查詢相應的數據,因為各個線程ID去查詢相應的數據,因為各個線程的ID不同,查到的數據自然也不同。

 

分兩種:

1.靜態TLS

_declspec(thread) DWORD data=0;

聲明了_declspec(thread)的變量,會為每一個線程創建一個單獨的拷貝。

 

2.動態TLS

 

 

TEB結構中,有個指針指向線程TLS數組,稱為_tls_array,利用這個數組指針可以管理線程相關的局部變量,這個數組由TLS_MINIMUM_AVAILABLE個元素組成,在WINNT.H文件中該值被定義為64個。

 

TlsAlloc函數    分配數組索引

DWORD WINAPI TlsAlloc(void);

系統對進程中的標志位進行檢索並找到一個FREE標志,然后系統會將該標志從FREE改為INUSE並讓TlsAlloc返回該標志位在位數組中的索引。

成功返回索引,失敗返回TLS_OUT_OF_INDEXES。

 

TlsSetValue函數   設置變量值

BOOL WINAPI TlsSetValue( DWORD dwTlsIndex, //索引值,表示在數組中的具體位置 LPVOID lpTlsValue //要設置的值 );

當一個線程調用TlsSetValue函數成功時,他會修改自己的PVOID數組,但它無法修改另一個線程TLS值。(只修改自己的)

 

TlsGetValue函數獲取變量值
 LPVOID WINAPI TlsGetValue( DWORD dwTlsIndex //索引值,表示在數組中的具體位置 );

返回在索引為dwTlsIndex  的TLS元素中保存的值,TlsGetValue只會查看屬於調用線程的數組。(只能查看自己的)

 

TlsFree函數  釋放索引

 

BOOL WINAPI TlsFree( DWORD dwTlsIndex //標記的索引值
)

 

 

 

函數會將進程內的標志位數組中對應的INUSE標志重新設回FREE,還會將所有線程中該元素的內容設置為0.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM