Как определить локальные локальные статические переменные типа thread?

Как определить локальные статические переменные (которые поддерживают его значение между вызовами функций), которые не используются для разных потоков?

Я ищу ответ как на C, так и на С++

Ответ 1

в Windows с использованием Windows API: TlsAlloc()/TlsSetValue()/TlsGetValue()

в Windows с использованием встроенного компилятора: используйте _declspec (thread)

в Linux (другой POSIX???): get_thread_area() и связанных с ним

Ответ 2

Просто используйте static и __thread в своей функции.

Пример:

int test(void)
{
        static __thread a;

        return a++;
}

Ответ 3

В текущем стандарте C нет модели для потоков или одинаковых, поэтому вы не можете получить ответ.

Утилита, предусмотренная POSIX для этого, pthread_[gs]etspecific.

Следующая версия стандарта C добавляет потоки и имеет концепцию локального хранилища потоков.

Ответ 4

Вы также можете использовать добавление локальных хранилищ потока С++ 11, если у вас есть доступ к С++ 11.

Ответ 5

Вы можете создать собственное собственное поточное хранилище как одноточечное для каждого идентификатора потока. Что-то вроде этого:

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.
}

Ответ 6

Вы можете создать структуру данных, выделенную из кучи для каждого потока.

Пример:

struct ThreadLocal
{
    int var1;
    float var2;
    //etc..
}