Chapter: Multicore Application Programming For Windows, Linux, and Oracle Solaris - Windows Threading

| Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail |

Allocating Thread-Local Storage

Thread-local storage enables each thread in an application to store private copies of data.

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;

 

}

 


Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail


Copyright © 2018-2020 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.