web-dev-qa-db-ja.com

スレッドローカルローカル静的変数を定義する方法は?

異なるスレッド間で共有されないローカル静的変数(関数呼び出し間でその値を保持する)を定義するにはどうすればよいですか?

CとC++の両方で答えを探しています

21

windows APIを使用するWindowsの場合: TlsAlloc() /TlsSetValue()/ TlsGetValue()

コンパイラ組み込み関数を使用するWindowsの場合:use _ declspec(thread)

linuxの場合(他のPOSIX ???): get_thread_area() および関連

12
Rom

関数でstaticと__threadを使用するだけです。

例:

int test(void)
{
        static __thread a;

        return a++;
}
9
Lai Jiangshan

C++ 11にアクセスできる場合は、C++ 11スレッドローカルストレージの追加を使用することもできます。

2
David

現在のC標準にはスレッドなどのモデルがないため、答えを得ることができません。

そのためにPOSIXによって予測されるユーティリティはpthread_[gs]etspecific

C標準の次のバージョンはスレッドを追加し、スレッドローカルストレージの概念を持っています。

2
Jens Gustedt

スレッド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.
}
1
GreenScape