web-dev-qa-db-ja.com

クラスまたは構造内でスレッドローカル変数を使用できますか

このような。

struct some_struct
{
 // Other fields
 .....
 __thread int tl;
}

私はそれをしようとしていますが、コンパイラは私にこのエラーを与えています。

./cv.h:16:2: error: '__thread' is only allowed on variable declarations
        __thread int tl;
22
pythonic

スレッドローカルストレージは静的変数にのみ適用されます。非静的構造またはクラスメンバーをスレッドローカルにしても意味がありません。

ローカル(自動)変数は常にコードを実行するスレッドに固有ですが、グローバル変数と静的変数はデータまたはBSSセグメントに存在するため、スレッド間で共有されます。 TLSは、これらのグローバル変数をスレッドに対してローカルにするメカニズムを提供します。これが___thread_キーワードによって実現されます。これは、コンパイラーに、各スレッドに変数の個別のコピーを作成するように指示します。同じ実行スレッド内で呼び出されるさまざまな関数からアクセスできます)。

非静的クラスメンバーと構造メンバーは、オブジェクト(クラスまたは構造)が割り当てられているのと同じ場所に配置されます-自動変数が宣言されている場合はスタック上、またはnewまたはmalloc() 使用されている。どちらの方法でも、各スレッドが変数の一意の格納場所を受け取り、___thread_はこの場合は適用されないため、コンパイラエラーが発生します。

15
Hristo Iliev

gccは、__threadの使用に次の 制限 を課します。

__thread指定子は、クラスのグローバル、ファイルスコープの静的、関数スコープの静的、または静的データメンバーに適用できます。ブロックスコープの自動または非静的データメンバーには適用できません。

__thread修飾子は、複数のコンパイラでサポートされています。厳密な制限がコンパイラによって多少異なることは想像に難くありません。

7
NPE

C11標準セクション6.7.1パラグラフ2

_Thread_localがstaticまたはextern.120で表示される場合を除いて、最大で1つのストレージクラス指定子を宣言の宣言指定子で指定できます。

C11標準セクション6.7.1パラグラフ

ブロックスコープを持つオブジェクトの宣言で、宣言指定子に_Thread_localが含まれている場合、それらにはstaticまたはexternも含まれます。 _Thread_localがオブジェクトの宣言に含まれている場合、そのオブジェクトのすべての宣言に含まれている必要があります。

4
phoxis

__thread int tl;thread_local static int tl;に変更する必要があります

3
Lingxi

古いPetzoldの本「Programming Windows」(1241ページ)によれば、キーワード__declspec(thread)を使用して、変数をスレッドローカルとしてマークします。したがって、たとえば、__ declspec(thread)int iGlobal = 1;

クラスでこれができるとは思えません。変数を静的にすることもできます。 [編集]おそらくWindowsで実行していないことに気づきました... Windowsの回答が必要な人なら、これが関係しているのではないでしょうか。

2
C Johnson

Cの場合、これはあまり意味がありません。static(=グローバル)メンバーはC++の機能にすぎません。そして、新しいC11標準(_Thread_local)はそれを許可しません。これらの獣は基本的に、静的な保存期間を持つ変数が許可されていればどこでも許可されます。

C++の場合、これはstaticメンバーと同様にクラス内で理にかなっていますが、これがC++ 11で許可されている場合、私にはわかりません。

0
Jens Gustedt

このように書く:

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 に記載されているとおり

0
Ilya M