Потокобезопасная инициализация статических переменных в области функций в C11Linux

Anonymous
Потокобезопасная инициализация статических переменных в области функций в C11

Сообщение Anonymous »

Я хочу инициализировать статическую структуру с областью действия функции в многопоточной среде без использования мьютекса, чтобы быстрый путь (т. е. уже инициализированный) включал небольшие накладные расходы.
Инициализация происходит при первом вызове функции. Инициализация — это не простое присваивание: она включает в себя вызовы других функций.
typedef /* whatever */ some_t;

const some_t* func( void )
{
static some_t thing;
static atomic_bool initialized = false;

// Relaxed is ok here, since synchronization is provided below.
if ( !atomic_load_explicit( &initialized, memory_order_relaxed ) )
{
bool false_ = false;
if ( atomic_compare_exchange_strong( &initialized, &false_, true ) )
{
// Winner thread performs initialization.
}
else
{
// Loser threads wait for winner thread to complete initialization.
while ( !atomic_load_explicit( &initialized, memory_order_relaxed ) )
{
// Yield here?
}
}
}

return &thing;
}

Мои вопросы:
  • Есть ли лучший способ сделать это?
  • Должны ли проигравшие потоки уступить?
Изменить:
Приведенный выше код неверен, поскольку проигравшие потоки не ждут завершения инициализации победителем нить.
typedef /* whatever */ some_t;

const some_t* func( void )
{
static some_t thing;
static atomic_bool initialized = false;
static atomic_bool initialize_begin = false;

// Relaxed is ok here, since synchronization is provided below.
if ( !atomic_load_explicit( &initialized, memory_order_relaxed ) )
{
bool false_ = false;
if ( atomic_compare_exchange_strong( &initialize_begin, &false_, true ) )
{
// Winner thread performs initialization.

atomic_store( &initialized, true );
}
else
{
// Loser threads wait for winner thread to complete initialization.
while ( !atomic_load_explicit( &initialized, memory_order_relaxed ) )
{
// Yield here?
}
}
}

return &thing;
}


Подробнее здесь: https://stackoverflow.com/questions/798 ... les-in-c11

Вернуться в «Linux»