In order of locality:
- "local" variables
- instance variables
- thread local variables
- class variables
- "global" variables
Thread local variables are "global" to the current thread, but are invisible or exist as copies to all other threads.
These may be a fine place to put a ContextObject
in a concurrent process, thus avoiding the syntactic inconvenience and coupling of explicitly passing it around.
Java supports ThreadLocalVariable
s in its standard library (http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ThreadLocal.html
). They can be added to some other languages, such as C/C++.
Microsoft Visual C++ lets you declare global and static variables as thread-local.
If a link-loader had access to all the potential 'thread-local' variables prior to any threads firing up, it wouldn't be difficult to bind each variable to an offset from an initial frame pointer and allocate an initial space to carry them just below the stack start for each thread. With a dedicated register locating the bottom of the stack, access to these would be exactly
as expensive as access to parameter-local variables (i.e. an offset from a frame pointer). MSVC++ doesn't go quite this far, instead creating a per-DLL global array of data blocks.
But this isn't the case for MSVC++, which supports a dynamic link loader. The above optimization is not possible if new TLVs can pop into existence based on a dynamic link after one starts firing up the threads; it simply isn't possible to know how much space to prepare below the first stack frame for the TLVs. Actually, just reasoning about this one is pointless when it is so easy to just look it up:
- Windows Server 2003 and Windows XP: The Visual C++ compiler supports a syntax that enables you to declare thread-local variables: _declspec(thread). If you use this syntax in a DLL, you will not be able to load the DLL explicitly using LoadLibrary on versions of Windows prior to Windows Vista. If your DLL will be loaded explicitly, you must use the thread local storage functions instead of _declspec(thread). For an example, see Using Thread Local Storage in a Dynamic Link Library.
Obviously you can still use TLS, but it is more complicated than declaring static variables with _declspec(thread)
. It seems the only distinction in a DLL is that you can't use the API Entry point to consistently allocate the memory (you can still use it to dealloc).
In a multithreaded CommonLisp
s can be used as ThreadLocalVariable
s, by binding them in the entry point of the thread. This is true of DynamicScoping
in general (which is what SpecialVariable
See also: ThreadLocalStorage