зачем использовать локальное хранилище потоков (TlsAlloc, TlsGetValue, ets) вместо локальных переменных

мой вопрос в том, почему использовать механизм TLS вместо только локальных переменных в функции потока? Можете ли вы привести прекрасный пример, или в чем преимущество TLS над локальными vars? Спасибо, Матеуш!--1-->

5 ответов


TLS полезен для таких вещей, как информация о контексте сеанса пользователя, которая специфична для потока, но может использоваться в различных несвязанных методах. В таких ситуациях TLS более удобен, чем передача информации вверх и вниз по стеку вызовов.


Если вы можете использовать локальные переменные, то сделайте это, и вы неизменно можете использовать локальные. Только в крайнем случае вы должны использовать локальное хранилище потоков, которое страдает почти всеми теми же недостатками, что и глобальные переменные. Хотя вы ищете причину использовать локальное хранилище потоков, на самом деле лучше всего искать способы избежать этого!


вот хорошая ссылка от Intel на использование локального хранилища потоков для уменьшения синхронизации : https://software.intel.com/en-us/articles/use-thread-local-storage-to-reduce-synchronization


Я знаю один очень хороший пример использования TLS. Когда вы реализуете LIBC или переносите один из вариантов LIBC на новую платформу, вам нужно как-то "errno" переменная (которая на однопоточной плате просто extern int errno) быть уникальной для каждого потока. Функции LIBC просто сохраняют его в TLS текущего потока, а вызов errno просто считывает его из TLS. TLS-это способ сделать любой поток библиотеки безопасным. Вы храните любые данные в "статических" или "глобальных" данных в TLS, поэтому одна и та же функция вызов из другого потока не повредит ваши "статические" или "глобальные" переменные в другом потоке. Что делает вас функциями re entrant из разных потоков.


локальное хранилище потока может использоваться для эмуляции глобальных или статических переменных на основе на поток. "Нормальные" локальные переменные не могут.