Как правильно использовать Double-Checked Locking с барьером памяти в c ++? - PullRequest
0 голосов
/ 25 октября 2018

Я только что прочитал отличный блог 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 Ответ

0 голосов
/ 25 октября 2018

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...