如何定义线程局部本地静态变量?

时间:2011-09-30 06:20:10

标签: c++ c multithreading static thread-safety

如何定义不在不同线程之间共享的本地静态变量(在函数调用之间保持其值)?

我正在寻找C和C ++的答案

5 个答案:

答案 0 :(得分:12)

使用Windows API的Windows上的

TlsAlloc() / TlsSetValue()/ TlsGetValue()

在Windows上使用编译器内在函数

:使用_declspec(thread)

Linux上的

(其他POSIX ???):get_thread_area()和相关的

答案 1 :(得分:9)

在你的函数中使用static和__thread。

示例:

int test(void)
{
        static __thread a;

        return a++;
}

答案 2 :(得分:2)

当前的C标准没有线程或类似的模型,因此你无法得到答案。

POSIX预见的实用程序是pthread_[gs]etspecific

下一版本的C标准添加了线程,并具有线程本地存储的概念。

答案 3 :(得分:2)

如果您有权访问C ++ 11,也可以使用C ++ 11线程本地存储添加。

答案 4 :(得分:1)

您可以将自己的线程特定本地存储设置为每个线程ID的单例。像这样:

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();是一个特定于平台的函数,用于确定调用者的线程ID。像这样:

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