Звичайний шаблон для синглтон-класу - це щось на зразок
static Foo &getInst()
{
static Foo *inst = NULL;
if(inst == NULL)
inst = new Foo(...);
return *inst;
}
Однак я розумію, що це рішення не є безпечним для потоку, оскільки 1) конструктор Foo може бути викликаний більше одного разу (що може мати значення, а може і не мати) і 2) inst може бути не повністю побудований до того, як його повернуть в інший потік .
Одне з рішень - обернути мутекс навколо всього методу, але тоді я плачу за накладні витрати на синхронізацію ще довго після того, як мені це насправді потрібно. Альтернатива - це щось на зразок
static Foo &getInst()
{
static Foo *inst = NULL;
if(inst == NULL)
{
pthread_mutex_lock(&mutex);
if(inst == NULL)
inst = new Foo(...);
pthread_mutex_unlock(&mutex);
}
return *inst;
}
Це правильний спосіб зробити це, чи є якісь підводні камені, про які я повинен знати? Наприклад, чи можуть виникати проблеми із статичним порядком ініціалізації, тобто чи завжди гарантовано inst має значення NULL при першому виклику getInst?