How to define thread-local local static variables?

前端 未结 5 438
执笔经年
执笔经年 2020-12-09 16:48

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

相关标签:
5条回答
  • 2020-12-09 17:01

    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.

    0 讨论(0)
  • 2020-12-09 17:16

    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

    0 讨论(0)
  • 2020-12-09 17:20

    You can also use the C++11 thread local storage additions if you have access to C++11.

    0 讨论(0)
  • 2020-12-09 17:23

    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.
    }
    
    0 讨论(0)
  • 2020-12-09 17:24

    Just use static and __thread in your function.

    Example:

    int test(void)
    {
            static __thread a;
    
            return a++;
    }
    
    0 讨论(0)
提交回复
热议问题