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

大龍的博客

常用鏈接

統(tǒng)計(jì)

最新評(píng)論

線程局部存儲(chǔ)TLS

線程局部存儲(chǔ)(thread-local storage, TLS)是一個(gè)使用很方便的存儲(chǔ)線程局部數(shù)據(jù)的系統(tǒng)。利用TLS機(jī)制可以為進(jìn)程中所有的線程關(guān)聯(lián)若干個(gè)數(shù)據(jù),各個(gè)線程通過(guò)由TLS分配的全局索引來(lái)訪問(wèn)與自己關(guān)聯(lián)的數(shù)據(jù)。這樣,每個(gè)線程都可以有線程局部的靜態(tài)存儲(chǔ)數(shù)據(jù)。

用于管理TLS的數(shù)據(jù)結(jié)構(gòu)是很簡(jiǎn)單的,Windows僅為系統(tǒng)中的每一個(gè)進(jìn)程維護(hù)一個(gè)位數(shù)組,再為該進(jìn)程中的每一個(gè)線程申請(qǐng)一個(gè)同樣長(zhǎng)度的數(shù)組空間,如圖3.9所示。

圖3.9  TSL機(jī)制在內(nèi)部使用的數(shù)據(jù)結(jié)構(gòu)

運(yùn)行在系統(tǒng)中的每一個(gè)進(jìn)程都有圖3.9所示的一個(gè)位數(shù)組。位數(shù)組的成員是一個(gè)標(biāo)志,每個(gè)標(biāo)志的值被設(shè)為FREE或INUSE,指示了此標(biāo)志對(duì)應(yīng)的數(shù)組索引是否在使用中。Windodws保證至少有TLS_MINIMUM_AVAILABLE(定義在WinNT.h文件中)個(gè)標(biāo)志位可用。

動(dòng)態(tài)使用TLS的典型步驟如下。

(1)主線程調(diào)用TlsAlloc函數(shù)為線程局部存儲(chǔ)分配索引,函數(shù)原型為:

DWORD TlsAlloc(void);  // 返回一個(gè)TLS索引

如上所述,系統(tǒng)為每一個(gè)進(jìn)程都維護(hù)著一個(gè)長(zhǎng)度為TLS_MINIMUM_AVAILABLE的位數(shù)組,TlsAlloc的返回值就是數(shù)組的一個(gè)下標(biāo)(索引)。這個(gè)位數(shù)組的惟一用途就是記憶哪一個(gè)下標(biāo)在使用中。初始狀態(tài)下,此位數(shù)組成員的值都是FREE,表示未被使用。當(dāng)調(diào)用TlsAlloc的時(shí)候,系統(tǒng)會(huì)挨個(gè)檢查這個(gè)數(shù)組中成員的值,直到找到一個(gè)值為FREE的成員。把找到的成員的值由FREE改為INUSE后,TlsAlloc函數(shù)返回該成員的索引。如果不能找到一個(gè)值為FREE的成員,TlsAlloc函數(shù)就返回TLS_OUT_OF_INDEXES(在WinBase.h文件中定義為-1),意味著失敗。

例如,在第一次調(diào)用TlsAlloc的時(shí)候,系統(tǒng)發(fā)現(xiàn)位數(shù)組中第一個(gè)成員的值是FREE,它就將此成員的值改為INUSE,然后返回0。

當(dāng)一個(gè)線程被創(chuàng)建時(shí),Windows就會(huì)在進(jìn)程地址空間中為該線程分配一個(gè)長(zhǎng)度為TLS_MINIMUM_AVAILABLE的數(shù)組,數(shù)組成員的值都被初始化為0。在內(nèi)部,系統(tǒng)將此數(shù)組與該線程關(guān)聯(lián)起來(lái),保證只能在該線程中訪問(wèn)此數(shù)組中的數(shù)據(jù)。如圖3.7所示,每個(gè)線程都有它自己的數(shù)組,數(shù)組成員可以存儲(chǔ)任何數(shù)據(jù)。

(2)每個(gè)線程調(diào)用TlsSetValue和TlsGetValue設(shè)置或讀取線程數(shù)組中的值,函數(shù)原型為:

BOOL TlsSetValue(

  DWORD dwTlsIndex,     // TLS 索引

  LPVOID lpTlsValue                   // 要設(shè)置的值

);

LPVOID TlsGetValue(DWORD dwTlsIndex );       // TLS索引

TlsSetValue函數(shù)將參數(shù)lpTlsValue指定的值放入索引為dwTlsIndex的線程數(shù)組成員中。這樣,lpTlsValue的值就與調(diào)用TlsSetValue函數(shù)的線程關(guān)聯(lián)了起來(lái)。此函數(shù)調(diào)用成功,會(huì)返回TRUE。

調(diào)用TlsSetValue函數(shù),一個(gè)線程只能改變自己線程數(shù)組中成員的值,而沒(méi)有辦法為另一個(gè)線程設(shè)置TLS值。到現(xiàn)在為止,將數(shù)據(jù)從一個(gè)線程傳到另一個(gè)線程的惟一方法是在創(chuàng)建線程時(shí)使用線程函數(shù)的參數(shù)。

TlsGetValue函數(shù)的作用是取得線程數(shù)組中索引為dwTlsIndex的成員的值。

TlsSetValue和TlsGetValue分別用于設(shè)置和取得線程數(shù)組中的特定成員的值,而它們使用的索引就是TlsAlloc函數(shù)的返回值。這就充分說(shuō)明了進(jìn)程中惟一的位數(shù)組和各線程數(shù)組的關(guān)系。例如,TlsAlloc返回3,那就說(shuō)明索引3被此進(jìn)程中的每一個(gè)正在運(yùn)行的和以后要被創(chuàng)建的線程保存起來(lái),用以訪問(wèn)各自線程數(shù)組中對(duì)應(yīng)的成員的值。

(3)主線程調(diào)用TlsFree釋放局部存儲(chǔ)索引。函數(shù)的惟一參數(shù)是TlsAlloc返回的索引。

利用TLS可以給特定的線程關(guān)聯(lián)一個(gè)數(shù)據(jù)。比如下面的例子將每個(gè)線程的創(chuàng)建時(shí)間與該線程關(guān)聯(lián)了起來(lái),這樣,在線程終止的時(shí)候就可以得到線程的生命周期。整個(gè)跟蹤線程運(yùn)行時(shí)間的例子的代碼如下:

#include <stdio.h>                                   // 03UseTLS工程下

#include <windows.h>            

#include <process.h>

// 利用TLS跟蹤線程的運(yùn)行時(shí)間

DWORD g_tlsUsedTime;

void InitStartTime();

DWORD GetUsedTime();

UINT __stdcall ThreadFunc(LPVOID)

{       int i;

         // 初始化開(kāi)始時(shí)間

         InitStartTime();

         // 模擬長(zhǎng)時(shí)間工作

         i = 10000*10000;

         while(i--){}

         // 打印出本線程運(yùn)行的時(shí)間

         printf(" This thread is coming to end. Thread ID: %-5d, Used Time: %d "n",

                                                                                                       ::GetCurrentThreadId(), GetUsedTime());

         return 0;

}

int main(int argc, char* argv[])

{       UINT uId;

         int i;

         HANDLE h[10];

         // 通過(guò)在進(jìn)程位數(shù)組中申請(qǐng)一個(gè)索引,初始化線程運(yùn)行時(shí)間記錄系統(tǒng)

         g_tlsUsedTime = ::TlsAlloc();

         // 令十個(gè)線程同時(shí)運(yùn)行,并等待它們各自的輸出結(jié)果

         for(i=0; i<10; i++)

         {       h[i] = (HANDLE)::_beginthreadex(NULL, 0, ThreadFunc, NULL, 0, &uId);         }

         for(i=0; i<10; i++)

         {       ::WaitForSingleObject(h[i], INFINITE);

                   ::CloseHandle(h[i]);      }

         // 通過(guò)釋放線程局部存儲(chǔ)索引,釋放時(shí)間記錄系統(tǒng)占用的資源

         ::TlsFree(g_tlsUsedTime);

         return 0;

}

// 初始化線程的開(kāi)始時(shí)間

void InitStartTime()

{       // 獲得當(dāng)前時(shí)間,將線程的創(chuàng)建時(shí)間與線程對(duì)象相關(guān)聯(lián)

         DWORD dwStart = ::GetTickCount();

         ::TlsSetValue(g_tlsUsedTime, (LPVOID)dwStart);

}

// 取得一個(gè)線程已經(jīng)運(yùn)行的時(shí)間

DWORD GetUsedTime()

{       // 獲得當(dāng)前時(shí)間,返回當(dāng)前時(shí)間和線程創(chuàng)建時(shí)間的差值

         DWORD dwElapsed = ::GetTickCount();

         dwElapsed = dwElapsed - (DWORD)::TlsGetValue(g_tlsUsedTime);

         return dwElapsed;

}

GetTickCount函數(shù)可以取得Windows從啟動(dòng)開(kāi)始經(jīng)過(guò)的時(shí)間,其返回值是以毫秒為單位的已啟動(dòng)的時(shí)間。

一般情況下,為各線程分配TLS索引的工作要在主線程中完成,而分配的索引值應(yīng)該保存在全局變量中,以方便各線程訪問(wèn)。上面的例子代碼很清除地說(shuō)明了這一點(diǎn)。主線程一開(kāi)始就使用TlsAlloc為時(shí)間跟蹤系統(tǒng)申請(qǐng)了一個(gè)索引,保存在全局變量g_tlsUsedTime中。之后,為了示例TLS機(jī)制的特點(diǎn)同時(shí)創(chuàng)建了10個(gè)線程。這10個(gè)線程最后都打印出了自己的生命周期,如圖3.10所示。

 

posted on 2010-08-12 03:15 大龍 閱讀(588) 評(píng)論(0)  編輯 收藏 引用


只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            在线视频精品| 亚洲一区二区三区视频| 欧美xxx成人| 久久九九99| 亚洲欧美日韩国产中文在线| 99精品99| 欧美激情视频免费观看| 欧美阿v一级看视频| 欧美国产日韩一二三区| 亚洲国产另类久久精品| 看片网站欧美日韩| 欧美成人午夜77777| 亚洲精品一区二区三区婷婷月| 亚洲乱码一区二区| 午夜激情综合网| 免费h精品视频在线播放| 欧美日韩精品一区二区| 国产精品一区三区| 在线日韩欧美| 亚洲欧美日韩天堂| 欧美不卡视频一区| 99精品视频网| 久久女同精品一区二区| 欧美四级剧情无删版影片| 黄色av成人| 亚洲女同同性videoxma| 免费不卡欧美自拍视频| 亚洲精品视频一区| 久久aⅴ国产紧身牛仔裤| 欧美日本亚洲视频| 在线日本欧美| 久久嫩草精品久久久精品一| 亚洲精品国精品久久99热一| 欧美一级免费视频| 欧美日韩综合一区| 亚洲日韩欧美视频一区| 久久一区二区三区四区五区| 在线综合+亚洲+欧美中文字幕| 久久视频免费观看| 国产一区二区三区精品欧美日韩一区二区三区| 亚洲精品一区二区三区不| 久久久免费精品视频| 亚洲一区二区三区免费在线观看 | 亚洲精品欧美在线| 久久嫩草精品久久久精品一| 国产农村妇女精品| 亚洲女人小视频在线观看| 亚洲精品看片| 欧美成人有码| 亚洲日本欧美在线| 美女脱光内衣内裤视频久久影院| 亚洲综合国产激情另类一区| 欧美视频一区在线观看| 99视频在线观看一区三区| 欧美激情成人在线视频| 久久一区中文字幕| 亚洲高清在线观看| 欧美电影免费观看网站| 老司机aⅴ在线精品导航| 在线精品观看| 亚洲国产精品第一区二区| 午夜免费日韩视频| 亚洲视频一区| 日韩视频三区| 欧美日韩不卡在线| 一区二区三区不卡视频在线观看| 亚洲盗摄视频| 欧美精品一区在线播放| 日韩视频精品在线观看| 亚洲欧洲精品一区二区| 欧美女人交a| 亚洲图片在线| 亚洲欧美日韩一区二区三区在线| 国产欧美精品国产国产专区| 久久精品视频va| 久久精品一区二区三区不卡| 尤妮丝一区二区裸体视频| 免费在线亚洲欧美| 欧美高清视频一二三区| 亚洲一区二区三区777| 午夜视频在线观看一区二区三区 | 国产日韩亚洲欧美综合| 久久精品人人做人人爽| 久久gogo国模裸体人体| 亚洲精品久久久久久一区二区| 91久久精品www人人做人人爽| 欧美理论电影在线播放| 欧美在线免费视频| 欧美成人精品三级在线观看| 亚洲免费在线观看视频| 久久久久国产精品一区| 亚洲美女在线观看| 亚洲欧美日韩在线综合| 亚洲国产精品成人va在线观看| 最新高清无码专区| 国产日本欧美一区二区三区| 欧美刺激性大交免费视频| 欧美丝袜一区二区| 欧美激情麻豆| 国产亚洲午夜| 一区二区三区高清在线观看| 有坂深雪在线一区| 亚洲综合精品四区| 亚洲精品久久久蜜桃| 欧美在线精品免播放器视频| 一区二区三区日韩精品| 久久夜色精品亚洲噜噜国产mv| 亚洲特色特黄| 欧美电影资源| 欧美电影专区| 韩国精品主播一区二区在线观看| 日韩一区二区精品视频| 亚洲国产日韩一区| 欧美一区二区三区日韩| 亚洲女人天堂成人av在线| 欧美理论在线| 欧美激情亚洲| 亚洲第一毛片| 久久久久久久一区二区| 香蕉成人啪国产精品视频综合网| 欧美成年网站| 亚洲国语精品自产拍在线观看| 国产精品99久久不卡二区| 小黄鸭精品密入口导航| 亚洲一级黄色片| 欧美成人精品h版在线观看| 久久久久国产成人精品亚洲午夜| 欧美日韩国产麻豆| 亚洲国产精品女人久久久| 一色屋精品亚洲香蕉网站| 亚洲欧美色一区| 午夜精彩国产免费不卡不顿大片| 欧美日韩国产成人| 亚洲激情偷拍| 日韩一级在线| 欧美国产日韩亚洲一区| 你懂的视频一区二区| 韩国精品在线观看| 久久美女性网| 欧美激情一区二区三区高清视频| 原创国产精品91| 另类激情亚洲| 亚洲国产高清一区| 日韩午夜av在线| 欧美日韩一区二区三区视频| 日韩视频在线观看| 亚洲欧美日韩精品久久久| 国产精品入口麻豆原神| 亚洲欧美资源在线| 六月天综合网| 亚洲精品国产精品国自产在线 | 国产日韩视频| 久久综合网络一区二区| 欧美激情在线| 亚洲在线观看视频| 国产九区一区在线| 久久天堂成人| 99精品国产在热久久婷婷| 亚洲综合视频一区| 国一区二区在线观看| 欧美成人国产一区二区| 一区二区三区精品视频在线观看| 亚洲欧美日韩人成在线播放| 国产主播一区二区三区| 男女视频一区二区| 在线视频你懂得一区| 久久精品一区二区国产| 亚洲激情一区二区| 国产精品久久久久久久久动漫| 欧美一级精品大片| 亚洲高清久久网| 性娇小13――14欧美| 亚洲电影在线| 国产精品成人av性教育| 久久国产手机看片| 99re6这里只有精品| 久久久久久久一区二区| 日韩亚洲欧美一区二区三区| 国产欧美亚洲一区| 欧美精选午夜久久久乱码6080| 亚洲系列中文字幕| 欧美华人在线视频| 欧美在线观看一区| 99国产精品国产精品毛片| 国产一级一区二区| 欧美性事免费在线观看| 蜜臀va亚洲va欧美va天堂| 亚洲免费一区二区| 亚洲精品影视| 午夜精品久久一牛影视| 欧美亚洲一级片| 伊人久久综合| 国产精品资源在线观看| 欧美激情导航| 久久亚洲综合| 久久精彩免费视频| 小黄鸭精品密入口导航| 亚洲一区二区免费看| 一本色道久久综合一区| 亚洲欧洲精品一区二区三区波多野1战4|