Как инициализировать локальную переменную потока в С++?

Возможный дубликат:
C++11 thread_local в gcc - альтернативы
Есть ли способ полностью эмулировать thread_local с помощью __thread GCC?

Я хотел использовать С++ 11 thread_local для создания и использования переменной thread_local, но, поскольку она еще не поддерживается gcc, я использую специфичную для gcc __thread. То, как я объявил переменную,

myClass
{
public:

  static __thread int64_t m_minInt;

};
__thread int64_t myClass::m_minInt = 100;

При компиляции получаю ошибку типа

error: ‘myClass::minInt’ is thread-local and so cannot be dynamically initialized

Как это правильно сделать?

PS: версия gcc: 4.6.3


person polapts    schedule 22.08.2012    source источник
comment
@betabandido вопрос, который вы связали, обсуждает альтернативу thread_local в С++ 11. Мой вопрос в том, как использовать __thread из gcc. В частности, рассматриваемое сообщение об ошибке. Я пытался найти его в другом месте, но не смог. Спасибо.   -  person polapts    schedule 22.08.2012


Ответы (1)


Вам нужно использовать ленивую инициализацию.

myClass
{
public:

  static __thread int64_t m_minInt;
  static __thread bool m_minIntInitialized;

  static int64_t getMinInt();
};
__thread int64_t myClass::m_minInt;
__thread bool myClass::m_minIntInitialized;


int64_t myClass::getMinInt()
{
  if (!m_minIntInitialized)  // note - this is (due to __thread) threadsafe
  {
    m_minIntInitialized = true;
    m_minInt = 100;
  }

  return m_minInt;
}

m_minIntInitialized гарантированно равно нулю.

В большинстве случаев (спецификация ELF) он помещается в раздел .tbss, что является нулевым. инициализирован.

Для C++ — http://en.cppreference.com/w/cpp/language/initialization< /а>

Для всех остальных нелокальных статических и локальных переменных потока выполняется нулевая инициализация. На практике переменные, которые будут инициализированы нулями, помещаются в сегмент .bss образа программы, который не занимает места на диске и обнуляется операционной системой при загрузке программы.

person nothrow    schedule 22.08.2012
comment
Откуда вы знаете, что m_minIntInitialized изначально ложно? - person CygnusX1; 05.09.2013
comment
@ CygnusX1, я обновил ответ. - person nothrow; 06.11.2015
comment
У вас есть состояние гонки: другой поток может прочитать m_minInt после того, как флаг установлен в значение true, но до того, как переменная будет инициализирована; - person denis; 17.03.2016
comment
@gdy, как другой поток может мешать локальной переменной потока? - person nothrow; 17.03.2016
comment
@Йоссариан, о, верно - person denis; 22.03.2016