Как компилятор C++ реализует локальное хранилище потоков в C++0x?

Как компилятор С++ реализует локальное хранилище потоков в С++ 0x

Я искал это в Google. Но ничего не могу найти по этому поводу.

У кого-нибудь есть материалы по этому поводу??


person Yuncy    schedule 17.09.2010    source источник
comment
В стандарте C++ нет деталей реализации (или очень мало).   -  person Martin York    schedule 17.09.2010
comment
Теперь это может помочь: akkadia.org/drepper/tls.pdf   -  person Julio Guerra    schedule 18.01.2013


Ответы (3)


Прочтите статью Википедии.

Локальное хранилище потока не является чем-то особенным для C++. Иногда он носит разные имена, например «TLS» (просто сокращение от локального хранилища потока) или «хранилище для конкретного потока» (TSS).

Большинство операционных систем предоставляют API для доступа к хранилищу потоков. Например, в Windows есть набор функций API начиная с "TLS". Под капотом Win32 резервирует специальную область для различных данных для каждого потока, включая локальное хранилище пользовательского потока, доступное через определенный регистр ЦП (FS на x86). Linux предоставляет хранилище для конкретных потоков через API-интерфейсы pthread с такими именами, как pthread_key_create. , и они обычно реализуются с использованием аналогичной техники.

Возможно, ОС вообще не поддерживает. Однако, если ОС предоставляет уникальный для процесса идентификатор потока через API, тогда библиотека времени выполнения C++ может поддерживать что-то концептуально похожее на std::map<thread_id, per_thread_storage> внутри. Конечно, тогда возникает проблема, что такое per_thread_storage. Если бы программа была статически компонована, она могла бы быть чем-то вроде указателя на большую структуру со всеми локальными переменными хранения потока, объявленными в программе как элементы. Это упрощение, но общее представление вы поняли.

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

person Doug    schedule 17.09.2010
comment
Вы ответили, как разработчик приложения может реализовать TLS, но не ответили, как компилятор и загрузчик обрабатывают ключевое слово C++0x thread_local. - person doron; 17.09.2010
comment
@doron: Компилятор и загрузчик либо используют API-интерфейсы, предоставляемые операционной системой, либо сами делают что-то эквивалентное технике сопоставления, при этом программисту приложения не нужно писать какой-либо код. - person Doug; 17.09.2010

Глобальные переменные (или доступные для записи статические данные — WSD) обычно хранятся в блоке памяти отдельно от стека, кучи и кода. Блок WSD создается и инициализируется до начала выполнения кода исполняемого файла.

C++0x вводит ключевое слово thread_local, которое обеспечивает создание отдельного экземпляра глобальной переменной для каждого потока. Проблема в том, что для каждого потока необходимо загружать разные блоки.

Следующая трудность заключается в том, что адрес переменной не фиксируется во время компоновки и различен для каждого потока.

Есть два пути решения этого вопроса. Один из них заключается в том, чтобы компилятор сгенерировал вызов функции для получения правильного блока, а другой — изменить ABI для сохранения блока TLS в одном из регистров процессора. Затем это можно использовать со смещениями для доступа к правильной переменной thread_local.

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

Если вам нужны кровавые подробности, посмотрите здесь.

person doron    schedule 17.09.2010

Вы можете использовать boost::thread для переносимо обрабатывать TLS на разных платформах. Реализация каждого из них находится в коде и должна помочь вам понять, как различные системы обрабатывают эту область.

person Steve Townsend    schedule 17.09.2010
comment
В C++0x компилятор поддерживает TLS с ключевым словом thread_local. - person doron; 17.09.2010
comment
Использование boost нормально, но для записи некоторые компиляторы действительно купились на проблемное пространство. gcc.gnu.org/onlinedocs/gcc-3.3. 1/gcc/Thread-Local.html - person Tony Delroy; 17.09.2010
comment
а C++0x создает новое ключевое слово thread_local, которое делает то же самое, что и __thread в gcc. - person doron; 17.09.2010