Allocating
Thread-Local Storage
Thread-local storage enables each thread in an application to store
private copies of data. Each thread accesses the data in the same way but
cannot see the values held by other threads. In essence, it is “global” data
that has scope limited to the executing thread.
There are two approaches to thread-local storage.
The easiest approach is to use the __declspec(thread)
specifier to allocate a thread-local variable.
Listing 6.38 shows an example of this. In this code,
each thread holds the value passed into it in a thread-local variable.
Listing 6.38 Using
__declspec(thread) to Allocate a Thread-Local
Variable
#include <windows.h>
#include <process.h>
__declspec(thread)
int number=0;
unsigned int __stdcall work( void *param )
{
number =
(int)param;
printf( "Number = %i\n", number
); return 0;
}
int
_tmain( int argc, _TCHAR* argv[] )
{
HANDLE hthreads[8]; for (int i=0; i<8; i++)
{
hthreads[i]=(HANDLE) _beginthreadex(0, 0, &work, (void*)i, 0, 0 );
}
WaitForMultipleObjects( 8, hthreads, 1, INFINITE );
for (int i=0; i<8; i++) { CloseHandle( hthreads[i] ); } getchar();
return 0;
}
An alternative approach is to use the thread-local
storage API. A global index needs to be allocated by a call to TlsAlloc(). This index is shared between all threads, but the data that each
thread stores in the index will be private to the calling thread. The call TlsFree()
can be used to release a global index when the
thread-local storage that it provides is no longer needed.
Each thread can store data at the index with a call
to TlsSetValue() and can
read the thread-local data with a call to TlsGetValue().
In Listing 6.39, thread-local storage is used to
hold the value passed into each thread. When each thread is created, it gets
passed a unique value. This value is stored in thread-local storage by the
routine setdata(). The
routine getdata()
retrieves the thread-local value. Each thread calls setdata() and then sleeps for a second to allow the other threads to run before
retrieving the data with a call to getdata().
Listing 6.39 Using
Thread-Local Storage
#include
<windows.h>
#include
<process.h>
#include
<stdio.h>
DWORD TLSIndex;
void
setdata( int value )
{
printf( "Thread %i: Set value = %i\n", GetCurrentThreadId(),
value );
TlsSetValue(
TLSIndex, (void*)value );
}
void getdata()
{
int value;
value =
(int)TlsGetValue( TLSIndex );
printf( "Thread %i: Has value = %i\n", GetCurrentThreadId(),
value );
}
unsigned int __stdcall workerthread( void * data )
{
int value = (int)data;
printf( "Thread %i: Got value = %i\n", GetCurrentThreadId(),
value ); setdata( value );
Sleep( 1000 ); getdata(); return 0;
}
int _tmain( int argc, _TCHAR* argv[] )
{
HANDLE handles[8];
TLSIndex =
TlsAlloc(); for (int i=0; i<8; i++)
{
handles[i] = (HANDLE)_beginthreadex( 0, 0, &workerthread,
(void*)i, 0, 0 );
}
for (int i=0; i<8; i++)
{
WaitForSingleObject( handles[i], INFINITE );
}
TlsFree(
TLSIndex );
getchar();
return 0;
}
Related Topics
Privacy Policy, Terms and Conditions, DMCA Policy and Compliant
Copyright © 2018-2023 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.