... если есть недостатки с учетом барьеров / ограждений памяти ...?
Использовать volatile
Код, безусловно, рискует использовать устаревшее значение для _isInitialized
во 2-м тесте.
if (!_isInitialized) {
EnterCriticalSection(&_InitLock);
if (_isInitialized) // Risk
Чтобы обеспечить перечитывание _isInitialized
, используйте volatile
. @ JimmyB
// int _isInitialized = FALSE;
volatile int _isInitialized = FALSE;
Другие общие данные
Другие данные, кроме _isInitialized
, назначенные в ... do stuff ...
и используемые в более поздних *Код 1029 * рискует той же проблемой, поскольку оптимизация может читать other_data
перед первым if (!_isInitialized)
.
Код может использовать volatile other_data
.К сожалению, это может привести к неприемлемому снижению производительности.Альтернативы зависят от того, что находится внутри stuff
.
Стиль
Я бы сделал _isInitialized
локальным для функции, отбросил _
и избежал goto
.
int myproc(parameters...) {
static volatile int isInitialized = FALSE;
if (!isInitialized) {
EnterCriticalSection(&_InitLock);
if (!isInitialized) {
// ... do stuff ...
isInitialized = TRUE;
}
LeaveCriticalSection(&_InitLock);
}
// ... do more stuff ...
return(something)
}