Использование локальной памяти потока (TLS)


Локальная память потока (TLS) включает многопоточность того же самого процесса, используя индекс, назначенный функцией TlsAlloc, чтобы сохранить и получить значение, которое является локальным к потоку. В этом примере, индекс назначается тогда, когда запускается процесс. Когда запускается каждый поток, он выделяет блок динамической памяти и сохраняет указатель на эту память в слоте TLS, используя функцию TlsSetValue. Функция CommonFunc использует функцию TlsGetValue, чтобы обратиться к данным, связанным с индексом, который является локальным для вызывающего потока. Прежде, чем каждый поток заканчивает работу, он освобождает свою динамическую память. Прежде, чем процесс закончит работу, он вызывает функцию TlsFree, чтобы освободить индекс.

#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 main(VOID)
{
DWORD IDThread;
HANDLE hThread[THREADCOUNT];
int i;
// Назначим индекс TLS.
if ((dwTlsIndex = TlsAlloc()) == -1)
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);
TlsFree(dwTlsIndex);
return 0;
}
VOID ErrorExit (LPTSTR lpszMessage)
{
fprintf(stderr, "%s\n", lpszMessage);
ExitProcess(0);
}

 

Назад в оглавление темы
На главную страницу темы

Hosted by uCoz