《WINDOWS核心编程第5版》随笔记录21

条目1、使用线程局部存储区(Thread Local Storage)可以讲数据和一个指定的线程关联起来。(P565)

条目2、由于早期运行库中的大多数函数设计在单线程的基础上,为保证在多线程的情况下这些函数(特别是使用了静态变量/全局变量的函数)的行为不发生改变,C/C++运行库使用了TLS。(p565)

 

条目3、TLS技术分为:动态TLS和静态TLS。(P566)

 

条目4、动态TLS应用的四个函数:TlsAlloc、TlsSetValue、TlsGetValue、TlsFree。

TlsAlloc函数检索进程内的位标志为FREE的索引,把该索引的标志位INUSE、内容清零并返回。该索引对进程内的所有线程或以后新建的线程而言,都是处在可直接使用的状态。换句话说,线程1调用TlsAlloc返回索引3,那么其他线程再怎么调用TlsAlloc,也不会返回索引3。(P567)

 

TlsSetValue函数修改当前线程的TLS值,不会影响到其他线程。为了提升性能,系统不对TlsSetValue函数中的索引做错误检查。(P568)

 

TlsGetValue函数获取当前线程的TLS值。

 

TlsFree函数释放进程内已经预定的TLS索引,将其状态更改为FREE。

 

动态TLS示例:

//TlsDemo.c //compile:cl.exe TlsDemo.c //下面注释为其执行顺序 #include <windows.h> DWORD g_dwTlsIndex = -1; unsigned TlsProc1(void *unuse) { LPVOID lpValue = NULL; TlsSetValue(g_dwTlsIndex,(PVOID)1234);//2 Sleep(1000); lpValue = TlsGetValue(g_dwTlsIndex); //5 printf("TlsProc1:%d/n",(DWORD)lpValue); return 0; } unsigned TlsProc2(void *unuse) { LPVOID lpValue = NULL; TlsSetValue(g_dwTlsIndex,(PVOID)4567);//3 lpValue = TlsGetValue(g_dwTlsIndex); //4 printf("TlsProc2:%d/n",(DWORD)lpValue); return 0; } int main(void) { g_dwTlsIndex = TlsAlloc(); // 1 _beginthreadex(NULL,0,TlsProc1,NULL,0,NULL); _beginthreadex(NULL,0,TlsProc2,NULL,0,NULL); _getch(); }

 

条目5、静态TLS使用__declspec(thread)修饰符声明全局或静态(static)的TLS变量,TLS变量将被编译器放到.tls段中。

系统在载入应用程序时,将根据.tls段的大小分配足够的内存来保存所有的静态TLS变量。若进程新建了一个线程,那么系统也要为新线程分配一样大的内存来保存的静态TLS变量。如果在加载一个DLL时,DLL中也存在静态TLS变量,那么系统会为进程中的所有线程扩展其TLS的内存容量。如果卸载一个DLL时,DLL中存在静态TLS变量,那么系统会为进程中的所有线程缩减其TLS的内存容量。(P571)

 

静态TLS示例:

//TlsDemo.c //compile:cl.exe TlsDemo.c //下面注释为其执行顺序 #include <windows.h> __declspec(thread) DWORD g_dwTlsValue = 0; unsigned TlsProc1(void *unuse) { g_dwTlsValue = 0x12345678; // 1 Sleep(1000); printf("TlsProc1:0x%08x/n",g_dwTlsValue); //4 return 0; } unsigned TlsProc2(void *unuse) { g_dwTlsValue = 0x87654321; //2 printf("TlsProc2:0x%08x/n",g_dwTlsValue);//3 return 0; } int main(void) { _beginthreadex(NULL,0,TlsProc1,NULL,0,NULL); _beginthreadex(NULL,0,TlsProc2,NULL,0,NULL); _getch(); }

 

你可能感兴趣的:(thread,多线程,编程,windows,null,dll)