线程本地存储器——Windows核心编程学习手札之二十一
線程本地存儲器
——Windows核心編程學習手札之二十一
C/C++運行期庫使用線程本地存儲器,運行期庫是在多線程應用程序出現前設計的,因此運行期庫里的大多數函數是用于單線程應用程序的。函數strtok就是如此,函數初次調用strtok時,該函數傳遞一個字符串地址,并將字符串地址保存在自己的靜態變量中,當再次調用該函數并傳遞NULL時,函數就引用保存的字符串地址。在多線程環境下,一個線程可以調用strtok,然后在其再次調用strtok之前,另一個線程也調用了strtok,這種情況下,第二個線程會在第一個線程不知情情況下,讓strtok用一個新地址改寫strtok的靜態變量,而第一個線程再次調用strtok時將使用第二個線程的字符串,這樣會導致難以發現和排除的錯誤。
為解決上面問題, C/C++運行期庫使用了TLS,每個線程均被賦予自己的字符串指針,供strtok函數使用,類似的C/C++運行期庫函數還有asctime和gmtime。如應用程序嚴重依賴全局變量和靜態變量,那TLS能夠解決問題,但編程應盡量減少對這些變量的使用,而更多地依賴自動(基于堆棧的)變量和通過函數的參數傳遞的數據,因為基于堆棧的變量總是和特定的線程聯系的。
動態TLS:
先調用DWORD TlsAlloc()告訴系統對進程中的位標志進行掃描,找出FREE標志,然后系統將標志由FREE改為INUSE,并且TlsAlloc返回位數組中的標志的索引。
將一個值放入線程的數組中,調用
?????? BOOL TlsSetValue(
??????????????????? DWORD dwTlsIndex,
??????????????????? PVOID pvTlsValue);
函數將PVOID值放入線程的數組中,由dwTlsIndex參數標識的索引處。
若要從線線程的數組中檢索一個值,調用
?????? PVOID TlsGetVluae(DWORD dwTlsIndex);
當所有線程中不再需要保留TLS時隙的位置時,調用BOOL TlsFree(DWORD dwTlsIndex)告訴系統該時隙不再需要保留。
靜態TLS:
靜態TLS將數據和線程聯系起來,只需要進行如下聲明:
?????? __declspec(thread) DWORD gt_dwStartTime=0;
__declspec(thread)告訴編譯器,對應的變量應該放入可執行文件或DLL文件中自己的節中,后面的變量必聲明為函數中(或函數外)的一個全局變量或靜態變量。
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的线程本地存储器——Windows核心编程学习手札之二十一的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DLL的高级操作技术——Windows核
- 下一篇: 插入DLL和挂接API——Windows