Как C++ complier реализует потоковое локальное хранилище в C++ 0xКак компилятор C++ реализует локальное хранилище потоков в C++ 0x?
Я искал это в google. Но я ничего не могу с этим поделать.
У кого-нибудь есть материал об этом?
Как C++ complier реализует потоковое локальное хранилище в C++ 0xКак компилятор C++ реализует локальное хранилище потоков в C++ 0x?
Я искал это в google. Но я ничего не могу с этим поделать.
У кого-нибудь есть материал об этом?
Прочитать Wikipedia entry.
Нить-локальное хранилище не является чем-то особенным для C++. Иногда это происходит под разными именами, такими как «TLS» (просто аббревиатура потокового локального хранилища) или «потоковое хранилище» (TSS).
Большинство операционных систем предоставляют API для доступа к потоковому хранилищу. Например, Windows имеет bunch of API functions, начиная с «TLS». Под капотом Win32 резервирует специальную область для множества данных на потоке, включая локальное хранилище пользовательских потоков, доступное через определенный регистр процессора (FS на x86). Linux предоставляет потоковое хранилище через API-интерфейсы pthread с именами, такими как pthread_key_create, и они обычно реализуются с использованием аналогичной техники.
Возможно, что ОС не предоставляет никакой поддержки вообще. Однако, если ОС предоставляет уникальный идентификатор потока процесса через API, тогда библиотека времени выполнения C++ может поддерживать что-то концептуально как std::map<thread_id, per_thread_storage>
внутренне. Конечно, тогда есть проблема, что такое per_thread_storage
. Если программа была статически связана, она могла бы быть чем-то вроде указателя на большую структуру со всеми переменными хранилища нитей, объявленными в программе как элементы. Это упрощение, но вы получаете общую идею.
Доступ к переменным локального хранилища данных, очевидно, является не просто чтением или записью прямой памяти. Это потенциально довольно много больше, чем это. Если вы собираетесь использовать многопоточное локальное/специфическое хранилище в определенной функции, я бы рекомендовал сначала скопировать указатель на локальную область потока в локальную переменную.
Вы ответили, как разработчик приложения может реализовать TLS, но не то, как компилятор и загрузчик обрабатывают ключевое слово C++ 0x thread_local – doron
@ doron: компилятор и загрузчик либо используют API-интерфейсы, поддерживаемые операционной системой, либо сами делают что-то, что эквивалентно самой технике отображения, без необходимости программирования программистом какого-либо кода. – Doug
Глобальные переменные (или записываемые статические данные - WSD) обычно хранятся в блоке памяти отдельно от стека, кучи и кода. Блок WSD создается и инициализируется до того, как код исполняемого файла начнет работать.
C++ 0x вводит ключевое слово thread_local
, которое обеспечивает создание отдельного экземпляра глобальной переменной для потока. Проблема в том, что для каждого потока нужно загружать другой блок.
Следующая трудность заключается в том, что адрес переменной не фиксируется во времени связи и отличается для каждого потока.
Существует два пути решения этой проблемы. Один из них заключается в том, чтобы компилятор генерировал вызов функции для получения правильного блока, а другой - для изменения ABI для хранения блока TLS в одном из регистров процессора. Затем это можно использовать со смещениями для доступа к правильной переменной thread_local
.
Это отличается от поддержки библиотеки, где ОС хранит одно значение void*
, которое можно использовать, чтобы сохранить указатель на локальный блок потока, который был выделен в куче процесса.
Если вы хотите узнать подробности gory here.
Вы можете использовать boost::thread для переносимости TLS на разных платформах. Реализация на каждом из них находится в коде и должна помочь вам понять, как разные системы обрабатывают эту область.
В C++ 0x компилятор поддерживает TLS с помощью ключевого слова thread_local – doron
Использование boost отлично, но для записи некоторые компиляторы действительно купили в проблемное пространство. http://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Thread-Local.html –
Вы правы, я обновлю это. –
Стандарт C++ имеет ноль (или очень мало) деталей реализации. –
Это может теперь помочь: http://www.akkadia.org/drepper/tls.pdf –