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

無我

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

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

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

一、TLS簡(jiǎn)述和分類

我們知道在一個(gè)進(jìn)程中,所有線程是共享同一個(gè)地址空間的。所以,如果一個(gè)變量是全局的或者是靜態(tài)的,那么所有線程訪問的是同一份,如果某一個(gè)線程對(duì)其進(jìn)行了修改,也就會(huì)影響到其他所有的線程。不過我們可能并不希望這樣,所以更多的推薦用基于堆棧的自動(dòng)變量或函數(shù)參數(shù)來訪問數(shù)據(jù),因?yàn)榛诙褩5淖兞靠偸呛吞囟ǖ木€程相聯(lián)系的。

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

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

 

二、靜態(tài)TLS

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

之所以先講靜態(tài)TLS,是因?yàn)樗诖a中使用時(shí)非常簡(jiǎn)單,我們只需寫類似如下這一句:

__declspec(thread) DWORD myTLSData=0;

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

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

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

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

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

以上是包含靜態(tài)TLS變量的可執(zhí)行文件如何運(yùn)行的情況。我們?cè)賮砜纯碊LL的情況:

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

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

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

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

所以,請(qǐng)記住:如果某個(gè)DLL包含靜態(tài)TLS數(shù)據(jù),請(qǐng)不要對(duì)這個(gè)DLL采用顯式鏈接的方式,否則可能會(huì)出錯(cuò)!

 

三、動(dòng)態(tài)TLS

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

動(dòng)態(tài)TLS在程序?qū)崿F(xiàn)中比靜態(tài)TLS要稍微麻煩一些,需要通過一組函數(shù)來實(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)記為未使用。

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

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

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


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

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

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

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

<2025年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

導(dǎo)航

統(tǒng)計(jì)

公告

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

留言簿(9)

隨筆分類(173)

IT

Life

搜索

積分與排名

最新隨筆

最新評(píng)論

閱讀排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲国产视频一区| 亚洲在线视频免费观看| 亚洲国产高清一区二区三区| 欧美国产日韩精品免费观看| 久久精品国产亚洲一区二区三区| 亚洲日本成人在线观看| 久久爱www| 亚洲欧美日韩中文视频| 夜夜嗨av一区二区三区四区| 在线看一区二区| 在线观看亚洲一区| 狠狠色综合色区| 国内自拍一区| 国产亚洲二区| 狠狠噜噜久久| 国产精品夜色7777狼人 | 久久99在线观看| 欧美高清视频| 欧美激情久久久久久| 欧美va天堂va视频va在线| 你懂的视频一区二区| 欧美成人性网| 欧美成人激情视频| 亚洲国产国产亚洲一二三| 亚洲国产一区二区三区在线播 | 欧美一区91| 久久久99国产精品免费| 亚洲素人在线| 欧美午夜精品一区| 欧美三级特黄| 欧美精品偷拍| 欧美婷婷久久| 国产在线视频欧美| 91久久精品国产| 亚洲午夜一区| 久久中文欧美| 亚洲精品影院在线观看| 亚洲免费中文| 老司机成人在线视频| 欧美日韩在线高清| 国产一区二区三区在线观看网站| 国内精品福利| 日韩午夜激情| 久久久999精品免费| 亚洲国产另类久久精品| 亚洲午夜黄色| 毛片精品免费在线观看| 国产精品国产自产拍高清av| 国产视频久久久久久久| 99国产精品久久久| 久久精品日产第一区二区| 亚洲国产成人在线播放| 日韩一级大片| 久久国产一区| 欧美激情综合网| 欧美精品日韩精品| 激情久久婷婷| 欧美一区二区三区免费在线看| 免费日韩精品中文字幕视频在线| 夜夜嗨av色一区二区不卡| 久久亚洲国产成人| 欧美国产日韩一二三区| 韩国精品一区二区三区| 亚洲午夜久久久久久久久电影院 | 国产精品乱人伦中文| 尤物yw午夜国产精品视频| 亚洲一区二区三区乱码aⅴ蜜桃女 亚洲一区二区三区乱码aⅴ | 亚洲精品日韩欧美| 鲁大师成人一区二区三区| 国产精品午夜av在线| 亚洲精品视频在线| 欧美成人免费全部| 久久精品99国产精品日本| 欧美午夜在线| 一区二区三区四区精品| 亚洲国产精品精华液网站| 亚洲图片欧洲图片日韩av| 香蕉久久久久久久av网站| 欧美视频日韩视频在线观看| 久久av红桃一区二区小说| 9久re热视频在线精品| 狂野欧美激情性xxxx欧美| 欧美日韩免费一区二区三区视频| 亚洲国产精品123| 久久嫩草精品久久久久| 欧美一区二区在线看| 国产小视频国产精品| 久久久999精品| 久久久久99| 亚洲韩国日本中文字幕| 欧美激情精品久久久久久| 欧美成人69av| 一本色道久久综合亚洲精品高清 | 欧美精品一区二区精品网| 亚洲黑丝在线| 亚洲经典在线| 欧美日韩国产免费观看| 亚洲精品护士| 99热这里只有成人精品国产| 欧美视频1区| 欧美亚洲一区二区三区| 欧美亚洲日本一区| 欧美视频网址| 久久成人精品电影| 午夜精品久久久久久久久| 欧美日韩大陆在线| 亚洲激情视频在线播放| 亚洲三级毛片| 国产精品高清在线观看| 欧美一区日韩一区| 久久人体大胆视频| 亚洲久久成人| 日韩亚洲国产欧美| 国产一区二区三区黄视频| 欧美jizz19性欧美| 欧美色综合天天久久综合精品| 亚洲综合久久久久| 久久激情久久| 一本久久综合亚洲鲁鲁| 亚洲女同性videos| 亚洲精品美女久久7777777| 亚洲精品影视| 国产日韩欧美在线播放不卡| 免费一区视频| 欧美成年人视频网站| 精品二区视频| 亚洲国产精品美女| 国产精品日韩欧美一区二区| 亚洲午夜一级| 亚洲制服少妇| 夜夜嗨av一区二区三区四季av | 久久久av网站| 亚洲自拍偷拍福利| 久久综合中文字幕| 夜夜精品视频一区二区| 亚洲一区二区三区久久| 国产精品v片在线观看不卡 | 麻豆久久婷婷| 久久久久久9999| 国产精品久久一卡二卡| 亚洲激情视频在线观看| 国产一区二区三区视频在线观看| 日韩视频第一页| 亚洲激情电影在线| 久久精品国产清高在天天线| 午夜精品成人在线| 欧美日韩日韩| 久久―日本道色综合久久| 欧美日韩综合视频网址| 久久精品欧洲| 久久久水蜜桃av免费网站| 欧美一区二区国产| 欧美三区美女| 夜夜爽99久久国产综合精品女不卡 | 国产精品欧美激情| 一本一本久久| 亚洲综合精品| 欧美三级资源在线| 亚洲裸体在线观看| 狠狠色丁香久久婷婷综合丁香| 妖精成人www高清在线观看| 韩国一区电影| 久久精品最新地址| 久久女同互慰一区二区三区| 国产精品一区2区| 亚洲欧美在线高清| 久久久久国产精品午夜一区| 国产精品视频九色porn| 在线亚洲一区观看| 亚洲在线1234| 国产精品性做久久久久久| 亚洲一品av免费观看| 午夜日韩激情| 国产视频久久久久久久| 欧美一区二区在线| 亚洲欧美精品在线观看| 国产精品大片免费观看| 亚洲一区免费在线观看| 久久久99精品免费观看不卡| 一区二区在线看| 欧美成人乱码一区二区三区| 亚洲精品国产精品乱码不99| 亚洲一区二区动漫| 国产精品麻豆成人av电影艾秋| 久久精品99久久香蕉国产色戒| 亚洲免费观看| 亚洲国内在线| 免费成人高清视频| 久久国产一区| 亚洲综合色婷婷| av成人毛片| 亚洲人体影院| 亚洲第一黄网| 黄色免费成人| 国产一区二区三区成人欧美日韩在线观看| 欧美日本不卡视频| 欧美不卡视频| 欧美成人69av| 最新日韩精品| 一区二区在线观看视频|