2009-08-13 2 views
56

В примере кодаЯвляются ли функции статическими переменными потокобезопасными в GCC?

void foo() 
{ 
    static Bar b; 
    ... 
} 

скомпилирован с GCC это гарантирует, что b будет создан и инициализирован в поточно-образом?

В справочной странице ССАГПЗ, нашел в -fno-поточно-статика командной строки вариант:

Не испустить дополнительный код, чтобы использовать процедуры, указанные в ++ ABI C для многопоточной инициализация местных статики. Вы можете использовать эту опцию в . Уменьшите размер кода немного в коде, чтобы не нуждался в потокобезопасности.

  1. Означает ли это, что местные статика являются потокобезопасными по умолчанию с GCC? Поэтому нет оснований для явной защиты, например. с pthread_mutex_lock/unlock?

  2. Как написать переносимый код - как проверить, добавит ли компилятор его охранники? Или лучше отключить эту функцию GCC?

ответ

41
  1. Нет, это означает, что инициализация локальных static с потокобезопасно.

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

+1

Какое использование инициализация с потоком, если у вас нет доступа к потокобезопасным (локальным функциям)? – xtofl

+10

Для инициализации мьютекса вы будете использовать для контроля доступа к другим переменным. – AProgrammer

+6

Если вам приходится писать переносимый код, вы не можете полагаться на инициализацию статической статистики по потоку. Например, MS C++ этого не делает. Поэтому я не согласен с пунктом 2 - вы можете безопасно отключить его, если хотите написать переносимый код, но вы не должны использовать функцию statics, где важна безопасность потоков ;-) – hirschhornsalz

5

Я думаю, что ключевая фраза

... поточно-инициализации из местной статики.

Я прочитал это как означающее, что это только инициализация статики, которая будет выполнена поточно-безопасным способом. Общее использование статики не будет потокобезопасным.

6

Это на самом деле не отвечает на ваши вопросы сразу (Charles already did that), но я думаю, что пришло время отправить ссылку на this article еще раз. Он проливает свет на инициализацию глобалов и должен быть прочитан и понят всем, кто пытается использовать переменные static в многопоточной среде.

17

У нас были серьезные проблемы с кодом блокировки, сгенерированным 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 не может понять это правильно)

+1

Я столкнулся с очень похожей ситуацией, и это заставило меня поставить этот вопрос здесь на SO – CsTamas

+1

'static SomeClass s();' является объявлением функции –

 Смежные вопросы

  • Нет связанных вопросов^_^