Мы используем класс, который хранит карту идентификатора потока в данных для реализации нашего локального хранилища потока. Кажется, это работает очень хорошо, тогда экземпляр этого класса можно разместить в любом месте, где вам требуется локальное хранилище потока. Обычно клиенты используют экземпляр в качестве статического частного поля.
Вот примерный набросок кода
template <class T>
struct ThreadLocal {
T & value()
{
LockGuard<CriticalSection> lock(m_cs);
std::map<int, T>::iterator itr = m_threadMap.find(Thread::getThreadID());
if(itr != m_threadMap.end())
return itr->second;
return m_threadMap.insert(
std::map<int, T>::value_type(BWThread::getThreadID(), T()))
.first->second;
}
CriticalSection m_cs;
std::map<int, T> m_threadMap;
};
Это затем используется как
class A {
// ...
void doStuff();
private:
static ThreadLocal<Foo> threadLocalFoo;
};
ThreadLocal<Foo> A::threadLocalFoo;
void A::doStuff() {
// ...
threadLocalFoo.value().bar();
// ...
}
Это просто и работает на любой платформе, где вы можете получить идентификатор потока. Обратите внимание, что критический раздел используется только для возврата / создания ссылки, если у вас есть ссылка, все вызовы находятся за пределами критического раздела.