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