Как определить локальные статические переменные (которые поддерживают его значение между вызовами функций), которые не используются для разных потоков?
Я ищу ответ как на C, так и на С++
Как определить локальные статические переменные (которые поддерживают его значение между вызовами функций), которые не используются для разных потоков?
Я ищу ответ как на C, так и на С++
в Windows с использованием Windows API: TlsAlloc()/TlsSetValue()/TlsGetValue()
в Windows с использованием встроенного компилятора: используйте _declspec (thread)
в Linux (другой POSIX???): get_thread_area() и связанных с ним
Просто используйте static и __thread в своей функции.
Пример:
int test(void)
{
static __thread a;
return a++;
}
В текущем стандарте C нет модели для потоков или одинаковых, поэтому вы не можете получить ответ.
Утилита, предусмотренная POSIX для этого, pthread_[gs]etspecific
.
Следующая версия стандарта C добавляет потоки и имеет концепцию локального хранилища потоков.
Вы также можете использовать добавление локальных хранилищ потока С++ 11, если у вас есть доступ к С++ 11.
Вы можете создать собственное собственное поточное хранилище как одноточечное для каждого идентификатора потока. Что-то вроде этого:
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(); является специфичной для платформы функцией для определения идентификатора потока вызывающего. Что-то вроде этого:
int GetThreadId()
{
int id;
#ifdef linux
id = (int)gettid();
#else // windows
id = (int)GetCurrentThreadId();
#endif
return id;
}
Теперь в рамках функции потока вы можете использовать локальное хранилище:
void threadFunction(void*)
{
StorageManager::threadLocalStorage()->my_static_variable_1 = 5; //every thread will have
// his own instance of local storage.
}
Вы можете создать структуру данных, выделенную из кучи для каждого потока.
Пример:
struct ThreadLocal
{
int var1;
float var2;
//etc..
}