Как это.
struct some_struct
{
// Other fields
.....
__thread int tl;
}
Я пытаюсь это сделать, но компилятор дает мне эту ошибку.
./cv.h:16:2: error: '__thread' is only allowed on variable declarations
__thread int tl;
Как это.
struct some_struct
{
// Other fields
.....
__thread int tl;
}
Я пытаюсь это сделать, но компилятор дает мне эту ошибку.
./cv.h:16:2: error: '__thread' is only allowed on variable declarations
__thread int tl;
Потоковое локальное хранилище применяется только к статическим переменным. Нет смысла создавать нестатические структуры или члены класса thread-local.
Локальные (автоматические) переменные всегда относятся к потоку, который выполняет код, но глобальные и статические переменные распределяются между потоками, поскольку они находятся в сегменте данных или BSS. TLS обеспечивает механизм, чтобы сделать эти глобальные переменные локальными для потока и то, что достигает ключевое слово __thread
- он инструктирует компилятор создать отдельную копию переменной в каждом потоке, в то время как лексически она остается глобальной (например, она может быть доступ к которым осуществляется разными функциями, вызываемыми в одном потоке выполнения).
Нестатические члены класса и члены структуры размещаются в том же месте, где объект (класс или структура) распределяется - либо в стеке, если объявлена автоматическая переменная, либо в куче, если new
или malloc()
используется. В любом случае каждый поток получает уникальное место хранения для переменной, а __thread
просто неприменим в этом случае, следовательно, вы получаете ошибку компилятора.
gcc
накладывает следующие ограничения на использование __thread
:
Спецификатор
__thread
может быть применен к любому глобальному статическому статическому или статическому элементу класса класса, ограниченному файловыми системами, класса. Он не может применяться к автоматическому или нестатическому элементу данных с блочным диапазоном.
Модификатор __thread
поддерживается несколькими компиляторами. Не исключено, что точные ограничения несколько отличаются от компилятора к компилятору.
C11 стандарт Раздел 6.7.1 Пункт 2
В лучшем случае один спецификатор класса хранения может быть указан в спецификаторах объявлений в, за исключением того, что _Thread_local может появляться со статическими или extern.120)
C11 стандарт Раздел 6.7.1 Пункт 3
В объявлении объекта с областью блока, если спецификаторы объявления включают _Thread_local, они также должны включать либо статические, либо внешние. Если _Thread_local появляется в любом объявлении объекта, он должен присутствовать в каждом объявление этого объекта.
Вы должны изменить __thread int tl;
на thread_local static int tl;
Согласно старой книге Петцольда "Программирование Windows" (стр. 1241), вы помечаете переменную как поток локально, используя ключевые слова: __declspec (thread). Так, например: __declspec (поток) int iGlobal = 1;
Я сомневаюсь, что это может быть сделано в классе. Вы также можете сделать переменную статическую. [edit] только что понял, что вы, вероятно, не работаете в Windows... Поэтому я предполагаю, что для тех, кому нужен ответ на Windows, это может быть актуальным.
Для C это не имеет большого значения, члены static
(= global) - это только функция С++. И поэтому новый стандарт C11 (который вводит _Thread_local
) не позволяет этого. Этим зверям разрешены в основном везде, где допустима переменная со статической продолжительностью хранения.
Для С++ это может иметь смысл внутри класса как аналогичный элементу static
, но если это разрешено С++ 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