Как правильно использовать двойную проверку блокировки с барьером памяти в c ++?

Я только что прочитал отличный блог C ++ и опасности двойной проверки блокировки

И я не понимаю, почему мы должны использовать первый барьер памяти в Примере 12 (как показано ниже):

Singleton* Singleton::instance () {
Singleton* tmp = pInstance;
... // insert memory barrier
if (tmp == 0) {
Lock lock;
tmp = pInstance;
if (tmp == 0) {
tmp = new Singleton;
... // insert memory barrier
pInstance = tmp;
}
}
return tmp;
}

Безопасно ли изменить его на код ниже? Почему бы и нет?

Singleton* Singleton::instance () {
if (pInstance == 0) {
Lock lock;
if (pInstance == 0) {
Singleton* tmp = new Singleton;
... // insert memory barrier
pInstance = tmp;
}
}
return pInstance;
}

1

Решение

Нет, это не безопасно. Если прочитать три абзаца перед примером и два после него, потенциальной проблемой является система, в которой запись в pInstance выполняется (сбрасывается в память) в потоке B перед созданием Singleton был покраснел Тогда поток А мог прочитать pInstanceувидеть указатель как ненулевой и вернуть его, потенциально позволяя потоку A получить доступ к Singleton до того, как поток B закончил хранить его в памяти.

Первая промывка необходима, чтобы гарантировать, что промывка записей во время строительства Singleton были завершены до вы пытаетесь использовать его в другой теме.

В зависимости от оборудования, на котором вы работаете, это может не быть проблемой.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]