Thread: Thread Local Storage

  1. #1
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879

    Thread Local Storage

    ^ ^ ^
    So what is it used for exactly? Yes yes, I know it's used so that "Any thread of the process can subsequently use this index to store and retrieve values that are local to the thread." But can't you do that with pretty much any variable, as long as you do all the the synchronizing stuff properly?
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  2. #2
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Each thread gets its own storage slot. This makes it useful to store a thread specific value. The classic example is SetLastError(), GetLastError().

    Code:
    // On process intialization.
    // Get an index to an available slot.
    g_idxLastError = TlsAlloc();
    
    void SetLastError(DWORD dwErr)
    {
        TlsSetValue(g_idxLastError, (LPVOID) dwErr);
    }
    
    DWORD GetLastError(void)
    {
        return (DWORD) TlsGetValue(g_idxLastError);
    }
    Now, consider how you would implement that functionality without some sort of thread local storage. Another example is being able to return a pointer to something in a thread safe manner. See gethostbyname(), etc.

  3. #3
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    >>Now, consider how you would implement that functionality without some sort of thread local storage

    How about wrapping the thread in a class, and putting a member DWORD called lastError in it (with thread sync stuff and all)... Oh wait, is that the point of it - to eliminate the need for manual sync'ing?

    >>Another example is being able to return a pointer to something in a thread safe manner.
    I'm not sure what you mean by that. Could you give an example?
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  4. #4
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    >> How about wrapping the thread in a class, and putting a member DWORD called lastError in it (with thread sync stuff and all)... Oh wait, is that the point of it - to eliminate the need for manual sync'ing? <<

    But then, how do you access that class? You'd would have to pass around the class reference to every function that needed to access the lastError variable (which is nearly all of the Windows api functions).

    Or to put it another way, where are you going to store the class reference. Have a look at the TimerProc() callback. How are you going to get the class reference from within that callback?

    >> I'm not sure what you mean by that. Could you give an example? <<

    Well, the gethostbyname() function returns a pointer to memory, but it doesn't require you to free it. It can't use a static variable as the function can be used by multiple threads and only one instance of a static variable exists per process. Therefore, it (maybe) returns a pointer to dynamic memory and stores the pointer to that dynamic memory in TLS so it can be cleaned up when the thread exits. Using TLS for this purpose is generally not good design but should be noted.

    The easiest way to think of TLS is like a global variable, but every thread gets a unique copy. Therefore, we can use a thread specific variable like a global variable, but without losing multi-threading capability.

    In summary, we can usually pass around a variable intead of using TLS. However:
    - Passing around a variable can be cumbersome - think of the GetLastError() example.
    - Due to third party interface design it is not always possible. For example, it is not possible to pass a variable to the TimerProc() callback.

    Have a look at the xMsgBox code I posted recently. It uses TLS to pass data into a timer procedure and a hook callback, neither of which provide a method to pass data to, except for TLS or global variables.

  5. #5
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Ahh, I'd assumed earlier it was supposed to be used to pass data between threads...

    Ok, but wouldn't only 1 TLS slot ever get allocated? Once the function sets m_bTlsInitialized to TRUE, isn't that the same for every thread? So wouldn't there be problems with several threads overwriting each other's TLS data? And along the same lines, since the index is a global variable, wouldn't it be the same if you just used a global int (or pointer) without bothering about special TLS accessing functions?

    So in short, what I'm saying is, any function needing to access the TLS slot needs the index... but if it has some way of getting the index, then it should be able to get an actual variable in the exact same way. What makes TLS so special then?
    Last edited by Hunter2; 07-06-2004 at 03:37 PM.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  6. #6
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Using Thread Local Storage

    That example may clear things up, but in short, one slot is used by multiple threads to store whatever they want.

    gg

  7. #7
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Ooooo, so the same slot index holds separate values for each thread? Now I'm starting to see the usefulness... Thanks, that clears it up a lot (assuming I've finally gotten it straight)!
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Terminating secondary thread from another thread
    By wssoh85 in forum C++ Programming
    Replies: 13
    Last Post: 12-19-2008, 05:14 AM
  2. Thread Prog in C language (seg fault)
    By kumars in forum C Programming
    Replies: 22
    Last Post: 10-09-2008, 01:17 PM
  3. Local and Roaming Profiles
    By BobS0327 in forum Tech Board
    Replies: 6
    Last Post: 01-20-2008, 09:03 AM
  4. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  5. C++ Threading?
    By draggy in forum C++ Programming
    Replies: 5
    Last Post: 08-16-2005, 12:16 PM