书上说:
        当一个线程被创建时,windows就会在进程地址空间中为该线程分配一个长度为TLS_MINIMUM_AVAILABLE的数组,数组成员的值都被初始化为0。在内部,系统将此数组与该线程关联起来,保证只能在该线程中访问此数组中的数据。每个线程都有自己的数组,数组成员可以储存任何数据。
        
         一个线程只能改变自己线程数组中的成员的值,而没有办法为另一个线程设置TLS值。
        TlsSetValue和TlsGetValue分别用于设置和取得线程数组中特定成员的值,而他们使用的索引就是TlsAlloc函数的返回值。例如,TlsAlloc返回3,那就说明索引3被此进程中的每一个正在运行的和以后要被创建的线程保存起来,用以访问各自线程数组中对应的成员的值。
       我想问的是既然一个线程只能访问自己的线程数组,而上面又说索引3被很多线程保存,多个线程怎么根据一个索引访问不同的值?是怎么实现的?一个索引怎么可以指向不同的值?
       还有没一个进程唯一的维数组和,线程的线程数组长度为什么是一样的。下面是书上的例子:
//利用TLS跟踪线程的运行时间 
#include<stdio.h>
#include<windows.h>
#include<process.h>
DWORD g_tlsUsedTime;                      
void InitStartTime();
DWORD GetUsedTime();
UINT _stdcall ThreadFunc(LPVOID)
{
    int i;
    //初始化开始时间 
    InitStartTime();
    //模拟长时间工作 
    i=1000*1000;
    while(i--){}
    //打印出本线程运行的时间 
    printf("Thise thread is coming to end. Thread ID:%-5d,Used Time:%d\n",::GetCurrentThreadId(),GetUsedTime());
    
    getchar();
    return 0;
}
int main()
{
    UINT uId;
    int i;
    HANDLE h[10];
    //通过在进程位数组中申请一个索引,初始化线程运行时间记录系统 
    g_tlsUsedTime=::TlsAlloc();                               //这里只有一个索引,给下面十个线程共用还是我理解错了 ?
    //令十个线程同时运行,并等待它们各自的输出结果 
    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]);}
        //通过释放线程局部储存索引,释放释放时间记录系统占用的资源
     ::TlsFree(g_tlsUsedTime);
     return 0;
 }  
 //初始化线程的开始时间
 void InitStartTime()
 {
     DWORD dwStart=::GetTickCount();
     ::TlsSetValue(g_tlsUsedTime,(LPVOID)dwStart);
 }
 //取得一个线程已运行的时间
 DWORD GetUsedTime()
 {
     //获得当前时间,返回当前时间和线程创建时间的差值 
     DWORD dwElapsed=::GetTickCount();
     dwElapsed=dwElapsed-(DWORD)::TlsGetValue(g_tlsUsedTime);
     return dwElapsed;
 }     
位数组和线程数组到底是什么关系?          

解决方案 »

  1.   

    此索引非彼索引,TlsAlloc返回的“索引值”是进程全局有效的,这个值代表系统为进程开辟一个槽SLOT,在这个槽内部才是各个线程的数据。你理解的那个索引是系统隐含的,内部跟线程ID绑定,外部访问不到。
      

  2.   

    线程局部存储TLS
     
    堆栈中定义的局部变量,对多线程是安全的,因为不同的线程有自己的堆栈。而通常定义的全局变量,所有线程都可以作读写访问,这样它就不是线程安全的,为安全就有必要加锁互斥访问。而何为线程局部存储(TLS),简单的说,就是一个变量(通常是指针,指向具体的类型),每个线程都有一个副本,而在程序中可以按照相同的方式来访问,(比如使用相同的变量名,又或者都调用TlsGetValue),既然是都有副本,自然线程中互不影响。打个比方,就如同一个人,被克隆出三个,其中一个被砍了一刀,其它两人都不会受伤。
      

  3.   

    http://blog.csdn.net/complex_ok/article/details/4351673