Storing
Thread-Private Data
A single-threaded application might use global data to hold program
state. For example, a single-threaded word processor might have global
variables that hold the name of the document being edited or the current line
number.
In a multithreaded application, it is sometimes
necessary for each thread to hold some state. This state is private to the
thread but can be accessed by all the code that the thread executes. Returning
to the word processor example, if it opens multiple documents and each document
is handled by a single thread, then each thread will want to have a sepa-rate
variable to hold the name of the document and the current line number. This
data would be private to each thread—no other thread could read it. The
application may still have some global state—perhaps it records details of the
person using it—and all threads would have access to this same information.
There are various approaches that a thread can use
to store private data. The obvious way to do this would be to allocate an array
to hold the thread-private data for all threads and then use the ID of the
thread as an index into the array. This is a relatively straightforward
approach that may suffice in a number of situations. Listing 4.27 shows how an
array can be used to store data that is private, or local, to the thread. The
array MyData[] is
accessed by the ID of the currently executing thread. This allows each
thread to store data at a unique location in the
array.
Listing 4.27 Using
an Array to Store Thread-Local Data
int
MyData[20];
void
ThreadedCode(int parameter)
{
MyData[ GetMyThreadID() ] = parameter;
...
}
Another approach would be to store local thread data on the stack. Each
thread has a stack that is private to the thread. Consequently, a thread can
allocate data on the stack and have that data remain private to the thread. It
is not advisable to pass pointers to that data across to other threads, since
stack-based data is valid only while the thread is alive and while the stack
frame containing the data exists. Listing 4.28 shows an example of using the
stack to hold thread-local data.
Listing 4.28 Holding Thread-Local Data on the Stack
void ThreadedCode(int parameter)
{
int MyData = parameter;
...
}
Yet another way of allocating
data that is private to the thread is to use thread-local storage. As its name suggests, variables allocated to
thread-local storage are private to the thread. Most compilers support the __thread keyword. For example, the code shown in Listing 4.29 would declare an
integer variable named count that is
local to each thread.
Listing 4.29 Using
the __thread Specifier to Identify
Thread-Local Data
__thread int count;
void ThreadedCode(int parameter)
{
count = parameter;
...
}
Every time a thread referenced
the variable count, it
would access the value of the copy local to that thread.
Another approach to thread-local storage is to use
support functions to allocate and deallocate local variables. Listing 4.30
shows the rough outline of the approach. First an identifier needs to be
created to uniquely identify the thread-local variable. Using that identifier,
the thread can then read data from or write data to that variable. When the
thread has finished with the variable, the identifier needs to be deleted.
Listing 4.30 Using
an API to Manage Thread-Local Data
ID = Create ID();
Set Thread Local Data ( ID, Value );
Value = Get Thread Local Data ( ID );
Delete ID( ID );
Related Topics
Privacy Policy, Terms and Conditions, DMCA Policy and Compliant
Copyright © 2018-2023 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.