Я читал Керриска Интерфейс программирования Linux: Руководство по системному программированию Linux и UNIX, Глава 31 по теме. В эту главу включены данные, относящиеся к потокам (раздел 31.3.4), и локальное хранилище потоков (раздел 31.4). Темы были освещены на страницах 663-669.
Данные, специфичные для потока (pthread_key_create
, pthread_setspecific
, pthread_getspecific
, и друзья) выглядит более мощным, но, кажется, немного более громоздким в использовании, и, кажется, чаще использует диспетчер памяти.
Нить локального хранилища (__thread
в статических и глобальных объявлениях) выглядит немного менее мощным, так как он ограничен временем компиляции, но, похоже, его проще использовать, и он остается вне менеджера памяти во время выполнения.
Я могу ошибаться насчет менеджера памяти времени выполнения, поскольку за кулисами может быть код, вызывающий pthread_key_create
когда он сталкивается __thread
переменные.
Керриск не предложил сравнение / контраст двух стратегий, и он не дал рекомендации о том, когда использовать какой из них в данной ситуации.
Чтобы добавить контекст к вопросу: я оцениваю стороннюю библиотеку. Библиотека использует глобалы, делает не использовать блокировку, и я хочу использовать ее в многопоточной программе. Программа использует многопоточность для минимизации задержек в сети.
Есть ли победитель? Или есть разные сценарии, которые оправдывают использование одного или другого?
pthread_key_create
и друзья намного старше, и, следовательно, поддерживаются на большем количестве систем.
__thread
является относительным новичком, как правило, гораздо удобнее использовать и (согласно википедии) поддерживается в большинстве систем POSIX, которые все еще имеют значение: Solaris Studio C / C ++, IBM XL C / C ++, GNU C, Clang и Intel C ++ Compiler (системы Linux).
__thread
также имеет значительное преимущество в том, что его можно использовать из обработчиков сигналов (за исключением использования __thread
от dlopen
общая библиотека ed, смотрите это ошибка), потому что его использование не предполагает malloc
(с тем же исключением).
Интерфейсы pthread являются стандартом POSIX, поэтому они более переносимы. Используйте их, если вы собираетесь использовать код на чем-то, кроме системы Linux. С другой стороны, если вы строго используете gcc / linux, то механизм __thread, безусловно, проще в использовании. Просто помните, что это расширение, специфичное для gcc, и поддерживается не на всех платформах.