青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

無我

讓內(nèi)心永遠(yuǎn)燃燒著偉大的光明的精神之火!
靈活的思考,嚴(yán)謹(jǐn)?shù)膶崿F(xiàn)
豪邁的氣魄、頑強(qiáng)的意志和周全的思考

線程本地存儲TLS(Thread Local Storage)的原理和實現(xiàn)——分類和原理

本文為線程本地存儲TLS系列之分類和原理。

一、TLS簡述和分類

我們知道在一個進(jìn)程中,所有線程是共享同一個地址空間的。所以,如果一個變量是全局的或者是靜態(tài)的,那么所有線程訪問的是同一份,如果某一個線程對其進(jìn)行了修改,也就會影響到其他所有的線程。不過我們可能并不希望這樣,所以更多的推薦用基于堆棧的自動變量或函數(shù)參數(shù)來訪問數(shù)據(jù),因為基于堆棧的變量總是和特定的線程相聯(lián)系的。

不過如果某些時候(比如可能是特定設(shè)計的dll),我們就是需要依賴全局變量或者靜態(tài)變量,那有沒有辦法保證在多線程程序中能訪問而不互相影響呢?答案是有的。操作系統(tǒng)幫我們提供了這個功能——TLS線程本地存儲。TLS的作用是能將數(shù)據(jù)和執(zhí)行的特定的線程聯(lián)系起來。

實現(xiàn)TLS有兩種方法:靜態(tài)TLS和動態(tài)TLS。以下我們將分別說明這兩類TLS。

 

二、靜態(tài)TLS

1、使用靜態(tài)TLS

之所以先講靜態(tài)TLS,是因為他在代碼中使用時非常簡單,我們只需寫類似如下這一句:

__declspec(thread) DWORD myTLSData=0;

我們就為本程序中的每一個線程創(chuàng)建了一個獨立的DWORD數(shù)據(jù)。

__declspec(thread)的前綴是Microsoft添加給Visual C++編譯器的一個修改符。它告訴編譯器,對應(yīng)的變量應(yīng)該放入可執(zhí)行文件或DLL文件中它的自己的節(jié)中。__declspec(thread)后面的變量必須聲明為函數(shù)中(或函數(shù)外)的一個全局變量或靜態(tài)變量。不能聲明一個類型為__declspec(thread)的局部變量,你想,因為局部變量總是與特定的線程相聯(lián)系的,如果再加上這個聲明是代表什么意思?

2、靜態(tài)TLS原理

靜態(tài)TLS的使用是如此簡單,那么當(dāng)我們寫了如上代碼以后,操作系統(tǒng)和編譯器是怎么處理的呢?

首先,在編譯器對程序進(jìn)行編譯時,它會將所有聲明的TLS變量放入它們自己的節(jié),這個節(jié)的名字是.tls。而后鏈接程序?qū)碜运袑ο竽K的所有.tls節(jié)組合起來,形成結(jié)果的可執(zhí)行文件或DLL文件中的一個大的完整的.tls節(jié)。
然后,為了使含有靜態(tài)TLS的程序能夠運行,操作系統(tǒng)必須參與其操作。當(dāng)TLS應(yīng)用程序加載到內(nèi)存中時,系統(tǒng)要尋找可執(zhí)行文件中的.tls節(jié),并且動態(tài)地分配一個足夠大的內(nèi)存塊,以便存放所有的靜態(tài)TLS變量。應(yīng)用程序中的代碼每次引用其中的一個變量時,就要轉(zhuǎn)換為已分配內(nèi)存塊中包含的一個內(nèi)存位置。因此,編譯器必須生成一些輔助代碼來引用該靜態(tài)TLS變量,這將使你的應(yīng)用程序變得比較大而且運行的速度比較慢。在x86 CPU上,將為每次引用的靜態(tài)TLS變量生成3個輔助機(jī)器指令。如果在進(jìn)程中創(chuàng)建了另一個線程,那么系統(tǒng)就要將它捕獲并且自動分配另一個內(nèi)存塊,以便存放新線程的靜態(tài)TLS變量。新線程只擁有對它自己的靜態(tài)TLS變量的訪問權(quán),不能訪問屬于其他線程的TLS變量。

以上是包含靜態(tài)TLS變量的可執(zhí)行文件如何運行的情況。我們再來看看DLL的情況:

a、隱式鏈接包含靜態(tài)TLS變量的DLL

如果應(yīng)用程序使用了靜態(tài)TLS變量,并且隱式鏈接包含靜態(tài)TLS變量的DLL時,當(dāng)系統(tǒng)加載該應(yīng)用程序時,它首先要確定應(yīng)用程序的.tls節(jié)的大小,并將這個值與應(yīng)用程序鏈接的DLL中的所有.tls節(jié)的大小相加。當(dāng)在你的進(jìn)程中創(chuàng)建線程時,系統(tǒng)自動分配足夠大的內(nèi)存塊來存放所有應(yīng)用程序聲明的和所有隱含鏈接的DLL包含的TLS變量。

b、顯式鏈接包含靜態(tài)TLS變量的DLL

考慮一下,當(dāng)我們的應(yīng)用程序通過調(diào)用LoadLibrary,以便顯式鏈接到包含靜態(tài)TLS變量的DLL時,會發(fā)生什么情況呢?系統(tǒng)必須查看該進(jìn)程中已經(jīng)存在的所有線程,并擴(kuò)大它們的TLS內(nèi)存塊,以便適應(yīng)新DLL對內(nèi)存的需求。另外,如果調(diào)用FreeLibrary來釋放包含靜態(tài)TLS變量的DLL,那么與進(jìn)程中的每個線程相關(guān)的的TLS內(nèi)存塊又都應(yīng)該被壓縮。
對于操作系統(tǒng)來說,這樣的管理任務(wù)太重了。所以,雖然系統(tǒng)允許包含靜態(tài)TLS變量的庫在運行期進(jìn)行顯式加載,但是其包含TLS數(shù)據(jù)卻沒有進(jìn)行相應(yīng)的初始化。如果試圖訪問這些數(shù)據(jù),就可能導(dǎo)致訪問違規(guī)!

所以,請記?。喝绻硞€DLL包含靜態(tài)TLS數(shù)據(jù),請不要對這個DLL采用顯式鏈接的方式,否則可能會出錯!

 

三、動態(tài)TLS

1、使用動態(tài)TLS

動態(tài)TLS在程序?qū)崿F(xiàn)中比靜態(tài)TLS要稍微麻煩一些,需要通過一組函數(shù)來實現(xiàn):

DWORD TlsAlloc();//返回TLS數(shù)組可用位置的索引

BOOL TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue); //將調(diào)用線程的TLS數(shù)組索引dwTlsIndex處設(shè)為值lpTlsValue

LPVOID TlsGetValue(DWORD dwTlsIndex); //返回調(diào)用線程的TLS數(shù)組dwTlsIndex索引處的值

BOOL TlsFree(DWORD dwTlsIndex); //釋放所有線程的TLS數(shù)組位置索引dwTlsIndex,將該位置標(biāo)記為未使用。

有了以上四個函數(shù),我們可以發(fā)現(xiàn)使用動態(tài)TLS其實還是很容易很方便的。

2、動態(tài)TLS原理

讓我們看看windows用來管理TLS的內(nèi)部數(shù)據(jù)結(jié)構(gòu):


線程本地存儲器的位標(biāo)志顯示了該進(jìn)程中所有運行的線程正在使用的一組標(biāo)志。每個標(biāo)志均可設(shè)置為FREE或者INUSE,表示TLS插槽(slot)是否正在使用。Microsoft保證至少TLS_MINIMUM_AVAILABLE位標(biāo)志是可供使用的。另外,TLS_MINIMUM_AVAILABLE在WinNT.h中被定義為64。Windows2000將這個標(biāo)志數(shù)組擴(kuò)展為允許有1000個以上的TLS插槽。

而每一個線程擁有一個自己獨立的TLS slot數(shù)組,用于存儲TLS數(shù)據(jù)。
為了使用動態(tài)TLS,我們首先調(diào)用TlsAlloc()來命令系統(tǒng)對進(jìn)程的位標(biāo)志進(jìn)行掃描,找到一個可用的位置,并返回該索引;如果找不到,就返回TLS_OUT_OF_INDEXES。事實上,除此之外,TlsAlloc函數(shù)還會自動清空所有線程的TLS數(shù)組的對應(yīng)索引的值。這避免以前遺留的值可能引起的問題。
然后,我們就可以調(diào)用TlsSetValue函數(shù)將對應(yīng)的索引位保存一個特定的值,可以調(diào)用TlsGetValue()來返回該索引位的值。注意,這兩個函數(shù)并不執(zhí)行任何測試和錯誤檢查,我們必須要保證索引是通過TlsAlloc正確分配的。
當(dāng)所有線程都不需要保留TLS數(shù)組某個索引位的時候,應(yīng)該調(diào)用TlsFree。該函數(shù)告知系統(tǒng)將進(jìn)程的位標(biāo)志數(shù)組的index位置為FREE狀態(tài)。如果運行成功,函數(shù)返回TRUE。注意,如果試圖釋放一個沒有分配的索引位,將產(chǎn)生一個錯誤。
動態(tài)TLS的使用相對靜態(tài)TLS稍微麻煩一點,但是無論是將其用在可執(zhí)行文件中還是DLL中,都還是很簡單的。而且當(dāng)用在DLL中時,沒有由于DLL鏈接方式而可能產(chǎn)生的問題,所以,如果要在DLL中用TLS,又不能保證客戶始終采用隱式鏈接方式,那么請采用動態(tài)TLS的實現(xiàn)。

主要參考文檔《windows核心編程》。

posted on 2012-07-04 08:57 Tim 閱讀(19599) 評論(0)  編輯 收藏 引用 所屬分類: 逆向工程 、windows系統(tǒng)

<2012年7月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

導(dǎo)航

統(tǒng)計

公告

本博客原創(chuàng)文章,歡迎轉(zhuǎn)載和交流。不過請注明以下信息:
作者:TimWu
郵箱:timfly@yeah.net
來源:m.shnenglu.com/Tim
感謝您對我的支持!

留言簿(9)

隨筆分類(173)

IT

Life

搜索

積分與排名

最新隨筆

最新評論

閱讀排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲精品免费看| 亚洲综合色噜噜狠狠| 国产精品久久夜| 久久一本综合频道| 亚洲一区制服诱惑| 亚洲精品一区二区三区99| 久久久国产91| 亚洲激情欧美| 亚洲美女av在线播放| 国产婷婷一区二区| 国产一区在线视频| 校园激情久久| 久久一区二区三区av| 久久精品日产第一区二区三区| 99在线|亚洲一区二区| 亚洲影视在线| 亚洲欧美日韩精品综合在线观看| 亚洲国产视频a| 久久综合九九| 亚洲日本精品国产第一区| 久久精品成人欧美大片古装| 一区二区三区视频在线看| 亚洲欧美日韩人成在线播放| 亚洲国产精品久久| 亚洲国产毛片完整版| 日韩视频不卡| 欧美在线看片a免费观看| 亚洲东热激情| 欧美激情影音先锋| 欧美成人免费va影院高清| 亚洲精品一区二区三区蜜桃久| 亚洲精品影视| 欧美日韩免费在线视频| 91久久精品日日躁夜夜躁欧美 | 欧美国产一区二区三区激情无套| 亚洲人成人一区二区三区| 另类专区欧美制服同性| 久热精品视频在线观看| 免费久久99精品国产自在现线| 国产精品久久一区主播| 亚洲无玛一区| 最新亚洲激情| 亚洲激情国产| 欧美激情视频一区二区三区在线播放| 欧美ed2k| 亚洲欧美变态国产另类| 中文在线一区| 国产精品卡一卡二| 亚洲欧美另类中文字幕| 国产日韩欧美精品在线| 亚洲区一区二区三区| 亚洲免费在线视频一区 二区| 国产精品久线观看视频| 亚洲国产精品v| 欧美天堂亚洲电影院在线播放 | 亚洲国产精品va在看黑人| 亚洲免费福利视频| 欧美国产高清| 亚洲国产欧美国产综合一区| 欧美连裤袜在线视频| 亚洲欧洲一区| 免费观看日韩av| 国产精品激情| 91久久精品一区二区别| 久久国产精品久久w女人spa| 久久精品欧美日韩| 久久高清免费观看| 久久精品在线观看| 欧美午夜片欧美片在线观看| 欧美韩国日本一区| 一区二区三区国产| 国产精品永久入口久久久| 亚洲欧美日韩精品久久亚洲区| 欧美一区二区三区久久精品| 国内成人精品视频| 欧美片第1页综合| 亚洲欧洲日产国产综合网| 亚洲美女在线国产| 欧美亚男人的天堂| 99re这里只有精品6| 亚洲一区二区三区视频| 国产精品自在线| 欧美在线视屏| 亚洲国产日韩欧美在线99| 亚洲一区二区三区乱码aⅴ蜜桃女| 在线免费精品视频| 欧美成人精品1314www| 亚洲午夜小视频| 国产精品色午夜在线观看| 欧美激情第10页| 亚洲日本在线观看| 亚洲成色999久久网站| 欧美成人免费在线| 亚洲欧美成人| 一区二区激情视频| 黄色综合网站| 欧美亚洲成人免费| 欧美黄色免费网站| 欧美日韩精品免费| 午夜精品视频网站| 小黄鸭精品aⅴ导航网站入口| 国产精品普通话对白| 欧美高清免费| 免费不卡在线视频| 久久精品视频在线| 欧美日韩一区二区三| 欧美成人精品激情在线观看 | 亚洲乱码国产乱码精品精天堂| 99精品欧美一区二区蜜桃免费| 午夜性色一区二区三区免费视频| 久久久综合香蕉尹人综合网| 久久se精品一区二区| 一区二区国产日产| 亚洲一区二区三区精品动漫| 久久成人这里只有精品| 亚洲欧美久久久| 亚洲三级性片| 亚洲乱码国产乱码精品精可以看| 久久综合图片| 9色国产精品| 午夜视频在线观看一区| 久久性天堂网| 韩日视频一区| 亚洲电影免费观看高清完整版在线观看 | 国产精品久久九九| 欧美午夜精品理论片a级按摩| 狂野欧美激情性xxxx| 亚洲免费在线电影| 国产亚洲一区在线| 欧美精品国产一区二区| 亚洲乱码视频| 久久人人看视频| 国产日韩精品视频一区| 另类尿喷潮videofree| 欧美精品久久久久a| 久久精品一区二区三区四区| 欧美成人午夜视频| 久久一本综合频道| 国产一级揄自揄精品视频| 亚洲一区国产| 亚洲欧美日韩国产综合在线| 欧美性做爰猛烈叫床潮| 中国成人在线视频| 性欧美超级视频| 国产性做久久久久久| 亚洲欧美日本国产有色| 性欧美长视频| 国产手机视频一区二区| 欧美在线播放| 蜜臀久久99精品久久久久久9| 国产真实久久| 久久综合久久综合久久综合| 欧美3dxxxxhd| 亚洲精选一区二区| 欧美日韩亚洲国产精品| 亚洲欧美影院| 欧美成人精品高清在线播放| 亚洲日韩中文字幕在线播放| 99视频有精品| 欧美日韩一区二区三区| 亚洲免费在线观看| 米奇777在线欧美播放| 亚洲美女诱惑| 国产日韩精品一区二区三区| 久久嫩草精品久久久精品一| 亚洲人成在线播放| 性亚洲最疯狂xxxx高清| 国精品一区二区三区| 欧美高清一区| 亚洲欧美日韩一区二区三区在线观看 | 亚洲日本成人| 亚洲美女啪啪| 久久噜噜亚洲综合| 欧美激情精品久久久久久大尺度| 亚洲黄色成人久久久| 欧美日韩亚洲一区| 午夜精品一区二区三区四区| 欧美激情精品| 欧美在线免费观看视频| 亚洲国产裸拍裸体视频在线观看乱了| 欧美久久精品午夜青青大伊人| 制服诱惑一区二区| 亚洲一区中文| 99在线|亚洲一区二区| 国产精品天天看| 欧美aaa级| 午夜精品视频一区| 日韩视频专区| 亚洲福利视频二区| 久久爱另类一区二区小说| 日韩午夜在线视频| 黄色精品免费| 国产精品日韩一区二区| 欧美成人精品一区二区三区| 性欧美video另类hd性玩具| 亚洲精品国产欧美| 久久久久久久久久久一区| 亚洲视频大全| 亚洲精品久久久蜜桃| 在线播放亚洲一区|