线程局部存储区
来源:互联网 发布:取消电视软件自动升级 编辑:程序博客网 时间:2024/05/03 23:18
尽量少使用全局变量和静态变量,尽量用栈上变量,也可用动态TLS和静态TLS
数据与对象实例关联起来
如SetWindowWord / SetWindowLong 将数据与窗口关联起来
进程中每个线程都有TLS_MINIMUM_AVAILABLE个PVOID值的数组,一旦一个线程预订了一个索引,进程内所有正在运行或将创建的线程都不能再使用这个索引
DWORD TlsAlloc();
TlsSetValue
TlsGetValue
TlsFree(DWORD index);
对DLL使用TLS,TlsAlloc放在DLL_PROCESS_ATTACH,TlsFree放在DLL_PROCESS_DETACH。 而index作为全局变量,但index不能其他用处会涉及多线程问题。
// dll project
// testdll.h
#ifdef TESTDLL_EXPORTS
#define TESTDLL_API __declspec(dllexport)
#else
#define TESTDLL_API __declspec(dllimport)
#endif
#include <Windows.h>
typedef struct _SomeStruct{
DWORD index;
DWORD tid;
char buf[256];
}SomeStruct,*PSomeStruct;
TESTDLL_API PSomeStruct Fun(PSomeStruct pSomeStruct);
//testdll.cpp
#include "testdll.h"
#include <iostream>
#include <Windows.h>
DWORD g_dwTlsIndex;
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
g_dwTlsIndex = TlsAlloc();
std::cout << "case DLL_PROCESS_ATTACH: TlsAlloc:" << g_dwTlsIndex << std::endl;
}
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
{
TlsFree(g_dwTlsIndex);
std::cout << "case DLL_PROCESS_DETACH: TlsFree:" << g_dwTlsIndex << std::endl;
}
break;
}
return TRUE;
}
TESTDLL_API PSomeStruct Fun(PSomeStruct pSomeStruct)
{
if( pSomeStruct != NULL )
{
pSomeStruct->index = g_dwTlsIndex;
if( TlsGetValue(g_dwTlsIndex) == NULL )
{
TlsSetValue(g_dwTlsIndex,HeapAlloc(GetProcessHeap(),0,sizeof(*pSomeStruct)));
}
memcpy(TlsGetValue(g_dwTlsIndex),pSomeStruct,sizeof(*pSomeStruct));
return NULL;
}
else
{
return (PSomeStruct)TlsGetValue(g_dwTlsIndex);
}
}
//test project
//main.cpp
#include <Windows.h>
#include "testdll\testdll.h"
#include <iostream>
#include <process.h>
unsigned __stdcall SecondThreadFunc( void* pArguments )
{
DWORD tid = GetCurrentThreadId();
SomeStruct ss = {0,tid,""};
memcpy(ss.buf,pArguments,strlen((const char*)pArguments));
Fun(&ss);
while(true)
{
PSomeStruct pget =Fun(NULL);
std::cout << "tlsindex:" << pget->index << " tid:" << tid << " buf:" << pget->buf << std::endl;
Sleep(2000);
}
_endthreadex( 0 );
return 0;
}
int wmain(int argc, wchar_t* argv[])
{
DWORD tid = GetCurrentThreadId();
SomeStruct ss = {0,tid,"11111111"};
Fun(&ss);
PSomeStruct pget =Fun(NULL);
std::cout << "tlsindex:" << pget->index << " tid:" << tid << " buf:" << pget->buf << std::endl;
HANDLE hThread1,hThread2;
unsigned threadID;
char *str1 = "first thread value";
char *str2 = "second thread value";
hThread1 = (HANDLE)_beginthreadex( NULL, 0, SecondThreadFunc, str1, 0, &threadID );
hThread2 = (HANDLE)_beginthreadex( NULL, 0, SecondThreadFunc, str2, 0, &threadID );
WaitForSingleObject( hThread1, INFINITE );
WaitForSingleObject( hThread2, INFINITE );
CloseHandle( hThread1 );
CloseHandle( hThread2 );
return 0;
}
//test result:
note: TLS 不要用多个索引存放一个数组,不如一个索引存放一个数组指针。
- 线程局部存储区
- 线程局部存储区(TLS)-之我见
- 第二十章 线程局部存储区
- windows核心编程---线程局部存储区
- MFC 线程局部存储
- 线程局部存储
- 线程局部存储TLS
- 线程局部存储
- 线程局部存储
- 线程局部存储TLS
- MFC线程局部存储
- TLS--线程局部存储
- 线程局部存储(TLS)
- 线程局部存储
- Java 线程局部存储
- 有关线程局部存储
- 线程局部存储(TLS)
- TLS--线程局部存储
- UVA 1401 Remember the Word
- 重启电脑时间总调整为2005-1-1
- 乱码问题
- Linux下C语言Socket实现文件传输
- openwrt下opencart安装
- 线程局部存储区
- [leetcode] 77 Combinations
- hdu1238---Substrings
- 苹果对非苹果用户免费开放iCloud套件服务
- 我用的判断点在多边形内的方法 c++
- python学习笔记第1天
- UVA 193 Graph Coloring
- 从头到尾彻底理解KMP
- HDU 4762 Cut the Cakes(数学题,推公式)