Являются ли статические переменные функции потокобезопасными в GCC?
В примере кода
void foo()
{
static Bar b;
...
}
составлен с GCC гарантируется ли, что b
будет создан и инициализирован потокобезопасным способом ?
в справочной странице gcc, нашел - fno-threadsafe-statics параметр командной строки:
не выдавайте дополнительный код для использования подпрограммы, указанные в C++ ABI для потокобезопасной инициализации местных статика. Вы можете использовать эту опцию для уменьшить размер кода немного в коде не нужно быть потокобезопасным.
означает ли это, что локальная статика является потокобезопасной по умолчанию с GCC ? Поэтому нет причин ставить явную охрану, например, с
pthread_mutex_lock/unlock
?Как написать портативный код - как проверить, если компилятор добавит свои охранники ? Или лучше отключить эту функцию GCC ?
4 ответа:
нет, это значит, что инициализации местных
static
s является потокобезопасным.вы определенно хотите оставить эту функцию включенной. Потокобезопасной инициализации местных
static
s очень важно. Если вам нужен вообще потокобезопасный доступ к localstatic
s тогда вам нужно будет добавить соответствующие охранники самостоятельно.
у нас были серьезные проблемы с кодом блокировки, сгенерированным GCC 3.4 для защиты локальной статической инициализации. Эта версия использовала глобальный общий мьютекс для защиты всех и любой статической инициализации, которые приводят к тупику в нашем коде. У нас была локальная статическая переменная, инициализированная из результата функции, которая запустила другой поток, который создал локальную статическую переменную. Псевдокод:
voif f() { static int someValue = complexFunction(); ... } int complexFunction() { start_thread( threadFunc() ); wait_for_some_input_from_new_thread(); return input_from_new_thread; } void threadFunc() { static SomeClass s(); ... }
единственным решением было отключить эту функцию gcc. Если вы нужно , чтобы ваш код был переносимым, что мы и сделали, вы все равно не можете зависеть от функции, добавленной в конкретную версию gcc для потокобезопасности. Предположительно C++0x добавляет потокобезопасную локальную статику, до тех пор это нестандартная магия, которая делает ваш код непереносимым, поэтому я советую против этого. Если вы решите использовать его, я предлагаю вам проверить, что ваша версия gcc не использует один глобальный мьютекс для этой цели написания образец заявления. (Трудность потокобезопасности очевидна из дело в том, что даже gcc не может получить это право)
Это на самом деле не отвечает на ваши вопросы сразу (Чарльз уже сделал это), но я думаю, что пришло время разместить ссылку на в этой статье еще раз. Он проливает свет на инициализацию глобалов и должен быть прочитан и понят всеми, кто пытается использовать
static
переменные в многопоточной среде.