В вашем коде показана действительная реализация шаблона двойной проверки блокировки (DCLP).
Синхронизация обрабатывается либо std::mutex
, либо std::atomic::instance
в зависимости от порядка, в котором потоки вводят код.
могут ли другие потоки видеть экземпляр как ненулевой, но почти_данный все еще ложный?
Нет, это невозможно.
Шаблон DCLP гарантирует, что все потоки, которые выполняют загрузку (которая возвращает ненулевое значение) в начале, гарантированно увидят instance
точку в допустимой памяти и almost_done==true
потому что загрузка синхронизирована с релизом магазина.
Причина, по которой можно подумать, что это возможно, заключается в небольшом окне возможностей, где первый поток (# 1) содержит std::mutex
, а второй поток (# 2) входит в первое if
-статмент ,
Перед тем как # 2 заблокирует std::mutex
, он может наблюдать значение для instance
(все еще указывая на несинхронизированную память, потому что мьютекс отвечает за это, но еще не синхронизировал).
Но даже если это произойдет (действительный сценарий в этом шаблоне), # 2 увидит almost_done==true
, так как ограничитель освобождения (вызываемый # 1) приказывает расслабленному магазину almost_done
до того, как магазин расслабился до instance
, и этот же порядок наблюдается другими потоками.