Die Initialisierung erfolgt, wenn die Funktion zum ersten Mal aufgerufen wird. Bei der Initialisierung handelt es sich nicht um eine einfache Zuweisung, sondern um Aufrufe anderer Funktionen.
Code: Select all
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;
}
- Gibt es einen besseren Weg, dies zu tun?
- Sollten Verlierer-Threads nachgeben?
Der obige Code ist nicht korrekt, da Verlierer-Threads nicht auf den Abschluss der Initialisierung durch den Gewinner warten Thread.
Code: Select all
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;
}
Mobile version