How to define thread-local local static variables?
Solution 1
on Windows using Windows API: TlsAlloc()/TlsSetValue()/TlsGetValue()
on Windows using compiler intrinsic: use _declspec(thread)
on Linux (other POSIX???) : get_thread_area() and related
Solution 2
Just use static and __thread in your function.
Example:
int test(void)
{
static __thread a;
return a++;
}
Solution 3
You can also use the C++11 thread local storage additions if you have access to C++11.
Solution 4
The current C standard has no model for threads or alike, so you can't get an answer, there.
The utility foreseen by POSIX for that is pthread_[gs]etspecific
.
The next version of the C standard adds threads and has a concept of thread local storage.
Solution 5
You can make your own thread specific local storage as singleton per thread ID. Something like this:
struct ThreadLocalStorage
{
ThreadLocalStorage()
{
// initialization here
}
int my_static_variable_1;
// more variables
};
class StorageManager
{
std::map<int, ThreadLocalStorage *> m_storages;
~StorageManager()
{ // storage cleanup
std::map<int, ThreadLocalStorage *>::iterator it;
for(it = m_storages.begin(); it != m_storages.end(); ++it)
delete it->second;
}
ThreadLocalStorage * getStorage()
{
int thread_id = GetThreadId();
if(m_storages.find(thread_id) == m_storages.end())
{
m_storages[thread_id] = new ThreadLocalStorage;
}
return m_storages[thread_id];
}
public:
static ThreadLocalStorage * threadLocalStorage()
{
static StorageManager instance;
return instance.getStorage();
}
};
GetThreadId(); is a platform specific function for determining caller's thread id. Something like this:
int GetThreadId()
{
int id;
#ifdef linux
id = (int)gettid();
#else // windows
id = (int)GetCurrentThreadId();
#endif
return id;
}
Now, within a thread function you can use it's local storage:
void threadFunction(void*)
{
StorageManager::threadLocalStorage()->my_static_variable_1 = 5; //every thread will have
// his own instance of local storage.
}
Comments
-
Hayri Uğur Koltuk almost 2 years
How to define local static variables (that keeps its value between function calls) that are not shared among different threads?
I am looking for an answer both in C and C++
-
Hayri Uğur Koltuk over 12 yearsafter reading on MSDN, Tls functions are exactly what i was looking for.
-
Mike Seymour over 12 years@Ali: no, it's an extension provided by GCC and a few other compilers. On MSVC, I think you use
__declspec(thread)
instead. -
Mike Seymour over 12 yearsYou'll also need synchronisation (such as a read/write mutex) to protect
m_storages
from access by multiple threads. -
zhaorufei almost 11 yearsNot only m_storages, but also std::map and the locally "static StorageManager instance;" is not thread safe. In native code implement a high efficiency singleton is not a easy task, see "C++ and the Perils of Double-Checked Locking" by Scott Meyers and Andrei Alexandrescu. erdani.com/publications/DDJ_Jul_Aug_2004_revised.pdf
-
Erik Aronesty about 9 years__thread works on linux, bsd, aix, and with the xl_c, gcc, and many other compilers. it can be trivially #defined to __declspec(thread) on windows.
-
Lothar over 6 yearsIt does not work with gcc or clang on macOS because it requires operating system support.