Если я определю статический __thread
переменная в глобальной области видимости, эквивалентна ли она обычной нестатической глобальной переменной? Другими словами, являются ли следующие две переменные эквивалентными друг другу, если они все находятся в глобальной области видимости:
int regular_global_int;
static __thread int static_thread_local_int;
Если ответ «нет», могу ли я узнать, в чем заключается основное различие между этими двумя и когда мне следует использовать какой?
Глобальные переменные, а в более общем случае переменные области имен, автоматически имеют статическую продолжительность хранения, если они не объявлены с помощью спецификатора класса хранения. На уровне пространства имен, static
не означает «длительность статической памяти»; это означает, что переменная имеет внутреннюю связь. следовательно
int x;
static int x;
в области имен пространства объявляют x
со статической продолжительностью хранения, но эти два объявления, тем не менее, не совпадают с тем, которое дает первое объявление x
внешняя связь, но вторая дает ему внутреннюю связь.
В том случае, если вы пишете
static thread_local int x;
thread_local
причины спецификатора класса хранения x
иметь локальную продолжительность потока (а не статическую продолжительность хранения), тогда как static
сам по себе снова имеет свое обычное значение в области имен пространства. Так x
является локальным потоком а также это имеет внутреннюю связь.
Я скомпилировал
int regular_global_int;
__thread int static_thread_local_int;
int main()
{
regular_global_int = 1;
static_thread_local_int = 1;
}
в http://ellcc.org/blog/?page_id=340 Мне пришлось снять статический, чтобы оптимизатор не избавился от статической переменной. я получил
main: # @main
# BB#0: # %entry
movl $1, regular_global_int(%rip)
movl $1, %fs:static_thread_local_int@TPOFF
xorl %eax, %eax
retq
для x86_64. Доступ к локальной переменной потока осуществляется по-разному, чтобы обеспечить локальное хранилище потока.