线程本地存储(TLS)使同一进程的多个线程可以使用TlsAlloc函数分配的索引来存储和检索线程本地的值。在此示例中,在进程开始时分配索引。当每个线程启动时,它分配一个动态内存块,并通过使用TLS索引将指针存储到该内存。TLS索引由本地定义的CommonFunc函数用于访问本地调用线程的数据。在每个线程终止之前,它释放其动态内存。
#include < stdio.h >
#include < windows.h >
#define THREADCOUNT 4
DWORD dwTlsIndex;
VOID ErrorExit(LPTSTR);
VOID CommonFunc(VOID)
{
LPVOID lpvData;
//检索当前线程的数据指针。
lpvData = TlsGetValue(dwTlsIndex);
if ((lpvData == 0) && (GetLastError() != 0))
ErrorExit("TlsGetValue error");
//使用为当前线程存储的数据。
printf("common: thread %d: lpvData=%lx\n",
GetCurrentThreadId(), lpvData);
Sleep(5000);
}
DWORD WINAPI ThreadFunc(VOID)
{
LPVOID lpvData;
//初始化此线程的TLS索引。
lpvData = (LPVOID) LocalAlloc(LPTR, 256);
if(!TlsSetValue(dwTlsIndex,lpvData))
ErrorExit("TlsSetValue error");
printf("thread %d: lpvData=%lx\n", GetCurrentThreadId(), lpvData);
CommonFunc();
//在线程返回之前释放动态内存。
lpvData = TlsGetValue(dwTlsIndex);
if (lpvData != 0)
LocalFree((HLOCAL) lpvData);
return 0;
}
DWORD主(VOID)
{
DWORD IDThread;
HANDLE hThread[THREADCOUNT];
int i;
//分配一个TLS索引。
if ((dwTlsIndex = TlsAlloc()) == 0xFFFFFFFF)
ErrorExit("TlsAlloc failed");
//创建多个线程。
for (i = 0; i < THREADCOUNT; i++)
{
hThread[i] = CreateThread(NULL, //没有安全属性
0, //使用默认堆栈大小
(LPTHREAD_START_ROUTINE) ThreadFunc, //线程函数
NULL, //没有线程函数参数
0, //使用默认创建标志
&IDThread); //返回线程标识符
//检查返回值是否成功。
if (hThread[i] == NULL)
ErrorExit("CreateThread error\n");
}
for (i = 0; i < THREADCOUNT; i++)
WaitForSingleObject(hThread[i], INFINITE);
return 0;
}
VOID ErrorExit(LPTSTR lpszMessage)
{
fprintf(stderr, "%s\n", lpszMessage);
ExitProcess(0);
}