LINUX.ORG.RU

Вопрос по использованию pthread_once()

 , ,


0

3

В качестве примера использования pthread_once() обычно приводится код наподобие следующего:

static pthread_once_t once = PTHREAD_ONCE_INIT;

void do()
{
  pthread_once(&once, &init);

  // do something
  ...
}

Но попался мне тут на днях в исходниках одного проекта немного другой пример использования:

void do()
{
  static pthread_once_t once = PTHREAD_ONCE_INIT;
  pthread_once(&once, &init);

  // do something
  ...
}

И закрались у меня подозрения что второй вариант не всегда гарантирует вызова init() только один раз в многопоточной программе т.к. в нем не исключены гонки при инициализации once. Развейте или подтвердите мои сомнения.



Последнее исправление: ricie (всего исправлений: 1)

Должно работать нормально, при инициализации статических переменных в функции gcc добовляет локи, такчто гонок быть не должно ...

zaz ★★★★
()

И закрались у меня подозрения что второй вариант не всегда гарантирует вызова init() только один раз в многопоточной программе т.к. в нем не исключены гонки при инициализации once. Развейте или подтвердите мои сомнения.

В С++11 (думаю как и в С11) инициализация статических переменных является обязательно thread-safe. Причем референсная реализация для стандарта была сделана как раз в GCC. Предыдущие стандарты не вводили понятие потоков, потому там это было на усмотрение разработчиков компилятора.

Pavval ★★★★★
()
Ответ на: комментарий от zaz

Должно работать нормально, при инициализации статических переменных в функции gcc добовляет локи, такчто гонок быть не должно

Про gcc я уже читал (кстати, там это можно и отключить задав опцию -fno-threadsafe-statics). Интересует что по этому поводу говорится в стандарте C/C++.

-fno-threadsafe-statics
Do not emit the extra code to use the routines specified in the C++ ABI for thread-safe initialization of local statics. You can use this option to reduce code size slightly in code that doesn't need to be thread-safe.

ricie
() автор топика
Ответ на: комментарий от Pavval

В С++11 (думаю как и в С11) инициализация статических переменных является обязательно thread-safe.

В каком разделе/параграфе почитать не подскажите?

ricie
() автор топика
Ответ на: комментарий от Pavval

думаю как и в С11

В C инициализаторами могут бить только константные выражения, т.е. там нечего защищать, при запуска всё уже лежит в готовом виде в data или bss.

xaizek ★★★★★
()

PTHREAD_ONCE_INIT вычисляется на этапе компиляции (иначе бы не было совместимости с Си, а заголовочник pthread.h общий), а значит любой нормальный компилятор пихнёт переменную в секцию данных и ничего в рантайме инициализироваться не будет, а значит и блокировки не нужны.

KivApple ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.