このような。
struct some_struct
{
// Other fields
.....
__thread int tl;
}
私はそれをしようとしていますが、コンパイラは私にこのエラーを与えています。
./cv.h:16:2: error: '__thread' is only allowed on variable declarations
__thread int tl;
スレッドローカルストレージは静的変数にのみ適用されます。非静的構造またはクラスメンバーをスレッドローカルにしても意味がありません。
ローカル(自動)変数は常にコードを実行するスレッドに固有ですが、グローバル変数と静的変数はデータまたはBSSセグメントに存在するため、スレッド間で共有されます。 TLSは、これらのグローバル変数をスレッドに対してローカルにするメカニズムを提供します。これが___thread
_キーワードによって実現されます。これは、コンパイラーに、各スレッドに変数の個別のコピーを作成するように指示します。同じ実行スレッド内で呼び出されるさまざまな関数からアクセスできます)。
非静的クラスメンバーと構造メンバーは、オブジェクト(クラスまたは構造)が割り当てられているのと同じ場所に配置されます-自動変数が宣言されている場合はスタック上、またはnew
またはmalloc()
使用されている。どちらの方法でも、各スレッドが変数の一意の格納場所を受け取り、___thread
_はこの場合は適用されないため、コンパイラエラーが発生します。
gcc
は、__thread
の使用に次の 制限 を課します。
__thread
指定子は、クラスのグローバル、ファイルスコープの静的、関数スコープの静的、または静的データメンバーに適用できます。ブロックスコープの自動または非静的データメンバーには適用できません。
__thread
修飾子は、複数のコンパイラでサポートされています。厳密な制限がコンパイラによって多少異なることは想像に難くありません。
C11標準セクション6.7.1パラグラフ2
_Thread_localがstaticまたはextern.120で表示される場合を除いて、最大で1つのストレージクラス指定子を宣言の宣言指定子で指定できます。
C11標準セクション6.7.1パラグラフ
ブロックスコープを持つオブジェクトの宣言で、宣言指定子に_Thread_localが含まれている場合、それらにはstaticまたはexternも含まれます。 _Thread_localがオブジェクトの宣言に含まれている場合、そのオブジェクトのすべての宣言に含まれている必要があります。
__thread int tl;
をthread_local static int tl;
に変更する必要があります
古いPetzoldの本「Programming Windows」(1241ページ)によれば、キーワード__declspec(thread)を使用して、変数をスレッドローカルとしてマークします。したがって、たとえば、__ declspec(thread)int iGlobal = 1;
クラスでこれができるとは思えません。変数を静的にすることもできます。 [編集]おそらくWindowsで実行していないことに気づきました... Windowsの回答が必要な人なら、これが関係しているのではないでしょうか。
Cの場合、これはあまり意味がありません。static
(=グローバル)メンバーはC++の機能にすぎません。そして、新しいC11標準(_Thread_local
)はそれを許可しません。これらの獣は基本的に、静的な保存期間を持つ変数が許可されていればどこでも許可されます。
C++の場合、これはstatic
メンバーと同様にクラス内で理にかなっていますが、これがC++ 11で許可されている場合、私にはわかりません。
このように書く:
template <class T> struct S {
thread_local static int tlm;
};
template <> thread_local int S<float>::tlm = 0; // "static" does not appear here
https://en.cppreference.com/w/cpp/language/storage_duration に記載されているとおり