Здесь все сложнее. Эта память будет создана во время работы приложения, как и обычная динамическая память. Идея та же. Используя этот тип памяти у нас отпадает необходимость заботиться о синхронизации памяти между потоками. Первое это надо запросить у системы индекс динамической локальной памяти потоков это делает TlsAlloc.
DWORD TlsAlloc(VOID);
Если функция успешна она вернет индекс памяти, иначе вернет -1;
DWORD dwTlsIndex; dwTlsIndex=TlsAlloc(); if (dwTlsIndex==-1) { cout << "Error TlsAlloc " << endl; return; }
В конце завершения работы потока индекс надо освободить. Это реализует функция -
BOOL TlsFree( DWORD dwTlsIndex //TLS index );
При успехе возвращаемое значение ненулевое.
if ( TlsFree( dwTlsIndex)==0 ) { cout << "Error TlsFree" << endl; return; }
К чему все это? Я понимаю, что на примере просто одной программы это не совсем понятно. А вот представьте себе, что Вы организуете DLL. К которой будут обращаться много программ. Ведь код DLL в памяти храниться в одном экземпляре. Соответственно надо гарантировать что каждый процесс, который обратиться к DLL будет иметь свою локальную динамическую память. Что бы один процесс не испортил данные другого процесса. Вот к чему все это. Хоть статическая локальная память процесса, хоть динамическая локальная память процесса нужна если к одной и той же функции будут обращаться много потоков. Обе эти памяти только по своему гарантируют локальность данных. К примеру, о DLL. В момент подключения процесса он должен создать свою динамическую локальную память, а в момент отключения освободить. То есть не процесс должен это делать в DLL должна уметь это делать. Вот примерно так. Это совсем простой пример так как в процессе может быть много потоков.
BOOL APIENTRY DllMain(HANDLE hInst, ULONG uCall, LPVOID lpReserved) { ...... switch(uCall) { case DLL_PROCESS_ATTACH: { dwTlsIndex = TlsAlloc(); ...... } case DLL_PROCESS_DETACH: { TlsFree(dwTlsIndex); ...... } ...... } ...... }
Ну и полный пример:
#include "stdafx.h" #include "windows.h" #include "iostream.h" #include "process.h" // специально для потока void fThredFunct1(void* pv); // декларация функции потока __declspec(thread) DWORD dwTlsIndex; // локальная статическая функция для потока void main() { ULONG hThread1 = 0; // Идентификатор потока 1 ULONG hThread2 = 0; // Идентификатор потока 2 //unsigned long _beginthread( void( __cdecl *start_address )( void * ), // unsigned stack_size, void *arglist ); hThread1 = _beginthread(fThredFunct1,0,NULL); // создали первый поток if (hThread1==-1) cout << "Error create thread" << endl; hThread2 = _beginthread(fThredFunct1,0,NULL); // создали второй поток if (hThread1==-2) cout << "Error create thread" << endl; Sleep(2000); // ждем } void fThredFunct1(void* pv) // реализация функции потока { dwTlsIndex=TlsAlloc(); // Запросить индекс if (dwTlsIndex==-1) // проверить на ошибку { cout << "Error TlsAlloc " << endl; return; } cout << dwTlsIndex << endl; Sleep(1000); if ( TlsFree( dwTlsIndex)==0 ) // освободить индекс { cout << "Error TlsFree" << endl; return; } }
Здесь два потока обращаться к одной и той же функции, которая в свою очередь получает индекс локальной динамической памяти потока. Для каждого потока он свой.