Я читал газету «Опасность двойной проверки блокировки Скоттом Мейерсом». http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
Автор приводит причины сбоя двойной блокировки (стр. 3, раздел 4). Я думал о способах обойти эту проблему без использования C ++ 11. Не то, чтобы я не хотел использовать C ++ 11, но просто чтобы посмотреть, возможно ли это решить без использования таких функций, как std :: call_once и т. Д.
class Singleton {
public:
static Singleton* instance();
private:
static Singleton* pInstance;
int someData_;
};Singleton* Singleton::instance()
{
class SeqAssign{
public:
SeqAssign(Singleton*& pInst, Singleton* pNew):
pInstance(pInst), pNewedInst(pNew){
}
~SeqAssign(){
pInstance = pNewedInst;
}
private:
Singleton*& pInstance;
Singleton* pNewedInst;
};
if (pInstance == 0) { // 1st test
Lock lock;
if (pInstance == 0) { // 2nd test
SeqAssign seq(pInstance, new Singleton);
}
}
return pInstance;
}
Будет ли код в Singleton :: instance () работать в многопоточной среде, так как порядок вызова конструктора и деструктора для класса SeqAssign является детерминированным.
№ Переменная pInstance
Доступ из более чем одного потока. Это
модифицируется. Код имеет неопределенное поведение. И я не уверен, что
ты вещь SeqAssign
будет делать, так как он не вводит никаких дополнительных
секвенирование между потоками.
В стандартном C ++ нет способа заставить работать двойную проверку журналирования; все
решений включают атомные переменные (возможно, реализованные с использованием
встроенный ассемблер) или нить локального хранилища.
Других решений пока нет …