異なるスレッド間で共有されないローカル静的変数(関数呼び出し間でその値を保持する)を定義するにはどうすればよいですか?
CとC++の両方で答えを探しています
windows APIを使用するWindowsの場合: TlsAlloc() /TlsSetValue()/ TlsGetValue()
コンパイラ組み込み関数を使用するWindowsの場合:use _ declspec(thread)
linuxの場合(他のPOSIX ???): get_thread_area() および関連
関数でstaticと__threadを使用するだけです。
例:
int test(void)
{
static __thread a;
return a++;
}
C++ 11にアクセスできる場合は、C++ 11スレッドローカルストレージの追加を使用することもできます。
現在のC標準にはスレッドなどのモデルがないため、答えを得ることができません。
そのためにPOSIXによって予測されるユーティリティはpthread_[gs]etspecific
。
C標準の次のバージョンはスレッドを追加し、スレッドローカルストレージの概念を持っています。
スレッド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.
}