Подтвердить что ты не робот

Можете ли вы использовать локальные переменные потока внутри класса или структуры

Как это.

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

Я пытаюсь это сделать, но компилятор дает мне эту ошибку.

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

Ответ 1

Потоковое локальное хранилище применяется только к статическим переменным. Нет смысла создавать нестатические структуры или члены класса thread-local.

Локальные (автоматические) переменные всегда относятся к потоку, который выполняет код, но глобальные и статические переменные распределяются между потоками, поскольку они находятся в сегменте данных или BSS. TLS обеспечивает механизм, чтобы сделать эти глобальные переменные локальными для потока и то, что достигает ключевое слово __thread - он инструктирует компилятор создать отдельную копию переменной в каждом потоке, в то время как лексически она остается глобальной (например, она может быть доступ к которым осуществляется разными функциями, вызываемыми в одном потоке выполнения).

Нестатические члены класса и члены структуры размещаются в том же месте, где объект (класс или структура) распределяется - либо в стеке, если объявлена ​​автоматическая переменная, либо в куче, если new или malloc() используется. В любом случае каждый поток получает уникальное место хранения для переменной, а __thread просто неприменим в этом случае, следовательно, вы получаете ошибку компилятора.

Ответ 2

gcc накладывает следующие ограничения на использование __thread:

Спецификатор __thread может быть применен к любому глобальному статическому статическому или статическому элементу класса класса, ограниченному файловыми системами, класса. Он не может применяться к автоматическому или нестатическому элементу данных с блочным диапазоном.

Модификатор __thread поддерживается несколькими компиляторами. Не исключено, что точные ограничения несколько отличаются от компилятора к компилятору.

Ответ 3

C11 стандарт Раздел 6.7.1 Пункт 2

В лучшем случае один спецификатор класса хранения может быть указан в спецификаторах объявлений в, за исключением того, что _Thread_local может появляться со статическими или extern.120)

C11 стандарт Раздел 6.7.1 Пункт 3

В объявлении объекта с областью блока, если спецификаторы объявления включают _Thread_local, они также должны включать либо статические, либо внешние. Если _Thread_local появляется в любом объявлении объекта, он должен присутствовать в каждом объявление этого объекта.

Ответ 4

Вы должны изменить __thread int tl; на thread_local static int tl;

Ответ 5

Согласно старой книге Петцольда "Программирование Windows" (стр. 1241), вы помечаете переменную как поток локально, используя ключевые слова: __declspec (thread). Так, например: __declspec (поток) int iGlobal = 1;

Я сомневаюсь, что это может быть сделано в классе. Вы также можете сделать переменную статическую. [edit] только что понял, что вы, вероятно, не работаете в Windows... Поэтому я предполагаю, что для тех, кому нужен ответ на Windows, это может быть актуальным.

Ответ 6

Для C это не имеет большого значения, члены static (= global) - это только функция С++. И поэтому новый стандарт C11 (который вводит _Thread_local) не позволяет этого. Этим зверям разрешены в основном везде, где допустима переменная со статической продолжительностью хранения.

Для С++ это может иметь смысл внутри класса как аналогичный элементу static, но если это разрешено С++ 11, я понятия не имею.