为了避免线程同步导致的效率问题,微软发明了TLS,即线程局部存储
- 静态使用,操作系统会保证每个TLS变量的下标都一样
- dll程序不能静态使用,因为dll中的代码可以在任何线程中运行,所以下标就不能固定了,而静态使用是下标一定是固定的
动态使用
int g_Number = 0; DWORD WINAPI WordThread(LPVOID lpParameter) { DWORD index=TlsAlloc(); TlsSetValue(index, 0); for (int i = 0;i < 100000000; i++) { TlsSetValue(index, LPVOID((int)TlsGetValue(index) + 1)); //g_Number++ } //TlsFree(index); 释放了里面存储的值就是0了 return (int)TlsGetValue(index); } #define MAX_THREADS 2 int main() { DWORD Start = GetTickCount(); HANDLE hThreads[MAX_THREADS] = {0}; for (int i = 0; i < MAX_THREADS; i++) { hThreads[i] = CreateThread(NULL, 0, WordThread, NULL, 0, NULL); } WaitForMultipleObjects(MAX_THREADS, hThreads, TRUE, -1); DWORD End = GetTickCount(); DWORD sum = 0; for (int i = 0; i < MAX_THREADS; i++) { DWORD dwExitCode = 0; (int)GetExitCodeThread(hThreads[i], &dwExitCode); sum += dwExitCode; } printf("time:%d g_Number:%d\n", End - Start, sum); return 0; }
静态使用
1 __declspec(thread) int g_Number = 0; 2 3 DWORD WINAPI WordThread(LPVOID lpParameter) { 4 5 for (int i = 0;i < 100000000; i++) { 6 g_Number++; 7 } 8 9 return g_Number; 10 }
TLS回调函数
VOID NTAPI TlsInit2(PVOID DllHandle, DWORD Reason, PVOID Reserved) { if (Reason == DLL_PROCESS_ATTACH) { printf("TlsInit2 DLL_PROCESS_ATTACH\n"); } else if (Reason == DLL_THREAD_ATTACH) { printf("TlsInit2 DLL_THREAD_ATTACH\n"); } else if (Reason == DLL_THREAD_DETACH) { printf("TlsInit2 DLL_THREAD_DETACH\n"); } else if (Reason == DLL_PROCESS_DETACH) { printf("TlsInit2 DLL_PROCESS_ATTACH\n"); } } #pragma data_seg(".CRT$XLB") //最后一个字符不固定,但不能是A PIMAGE_TLS_CALLBACK g_Callbacks[] = { &TlsAntiDebug, //&是标准写法,不加上的话换个编译器可能就报错了 &TlsInit1, &TlsInit2, NULL }; #pragma data_seg()
标签:TLS,index,int,TlsInit2,DLL,++,DWORD From: https://www.cnblogs.com/yewu1/p/17157113.html