среды
Блок, относящийся только к системам Майкрософт
thread
Модификатор расширенного класса хранилища используется для объявления локальной переменной потока. Для переносимого эквивалента в C++11 и более поздних версиях используйте описатель класса хранилища thread_local для переносимого кода. В Windows thread_local
реализовано с __declspec(thread)
помощью .
Синтаксис
__declspec(thread)
declarator
Замечания
Локальное хранилище потока (TLS) — это механизм, с помощью которого в каждом потоке многопоточного процесса выделяется хранилище для хранения данных определенного потока. В стандартных многопоточных программах данные совместно используются всеми потоками заданного процесса, в то время как локальное хранилище потоков является механизмом предоставления данных для конкретного потока. Полное обсуждение потоков см. в разделе "Многопоточность".
Объявления локальных переменных потока должны использовать расширенный синтаксис атрибута и __declspec
ключевое слово с thread
ключевое слово. В следующем примере кода показано, как объявлять целочисленную локальную переменную потока и инициализировать её некоторым значением:
__declspec( thread ) int tls_i = 1;
При использовании локальных потоковых переменных в динамически загруженных библиотеках необходимо учитывать факторы, которые могут привести к неправильной инициализации локальной переменной потока:
Если переменная инициализирована с помощью вызова функции (включая конструкторы), эта функция будет вызываться только для потока, вызвавшего загрузку двоичного или DLL-файла, и для этих потоков, запущенных после загрузки двоичного или DLL-файла. Функции инициализации не вызываются для любого другого потока, который уже выполнялся при загрузке библиотеки DLL. Динамическая инициализация происходит в вызове DllMain для DLL_THREAD_ATTACH, но библиотека DLL никогда не получает это сообщение, если библиотека DLL не в процессе при запуске потока.
Локальные переменные потока, инициализированные статически с константными значениями, обычно инициализированы должным образом во всех потоках. Однако по состоянию на декабрь 2017 года в компиляторе Microsoft C++ возникает известная проблема соответствия, в которой
constexpr
переменные получают динамическую, а не статическую инициализацию.Примечание. Обе эти проблемы, как ожидается, будут исправлены в будущих обновлениях компилятора.
Кроме того, при объявлении локальных объектов и переменных потока необходимо соблюдать следующие рекомендации.
Атрибут можно применять
thread
только к объявлениям и определениям и объявлениям данных класса;thread
нельзя использовать для объявлений или определений функций.Атрибут можно указать только для элементов данных со статическим сроком
thread
хранения. К ним относятся глобальные объекты данных (как и ), локальные статические объекты, такstatic
иextern
элементы статических данных классов. Нельзя объявлять автоматические объекты данных с атрибутомthread
.Атрибут необходимо использовать
thread
для объявления и определения локального объекта потока, будь то объявление и определение в одном файле или отдельных файлах.Атрибут нельзя использовать
thread
в качестве модификатора типа.Так как объявление объектов, использующих
thread
атрибут, разрешено, эти два примера семантически эквивалентны:// declspec_thread_2.cpp // compile with: /LD __declspec( thread ) class B { public: int data; } BObject; // BObject declared thread local. class B2 { public: int data; }; __declspec( thread ) B2 BObject2; // BObject2 declared thread local.
Стандарт C разрешает инициализацию объекта или переменной с выражением, включающим ссылку на себя, но только для нестатических объектов. Хотя C++ обычно разрешает такую динамическую инициализацию объекта с выражением, включающим ссылку на себя, этот тип инициализации не допускается с локальными объектами потока. Например:
// declspec_thread_3.cpp // compile with: /LD #define Thread __declspec( thread ) int j = j; // Okay in C++; C error Thread int tls_i = sizeof( tls_i ); // Okay in C and C++
sizeof
Выражение, включающее инициализированный объект, не представляет собой ссылку на себя и допускается в C и C++.
Завершение блока, относящегося только к системам Майкрософт
См. также
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по