关于双检查锁的问题
line50:在堆上创建对象,代码上的顺序为:先分配内存,再调用构造器进行初始化,最后将内存地址赋值给指针。
然而在CPU层面,指令级别,这3个顺序有可能被reorder,顺序变为:先分配内存,将内存地址赋值给指针,最后调用构造器。
此时如有线程进来,line47判断时,line50刚好在内存地址赋值给指针后,调用构造函数前,此时指针不为空。则line47判断不为空,返回指针。
以下为双检查锁线程安全,并且高并发读取高效的单例模式。
关于std::atomic:
每个 std::atomic 模板的实例化和全特化定义一个原子类型。若一个线程写入原子对象,同时另一线程从它读取,则行为良好定义(数据竞争的细节见内存模型)。
另外,对原子对象的访问可以建立线程间同步,并按std::memory_order所对非原子内存访问定序。
std::atomic 既不可复制亦不可移动