当前位置: 首页 > news >正文

张家港高端网站建设徐州设计网站

张家港高端网站建设,徐州设计网站,浙江省电子商务网站建设,wordpress 高级选项目录 饿汉式懒汉式双检查锁#xff0c;线程安全的版本什么是reorder#xff1f;解决内存读写reorder不安全方法代码解释懒汉式的优缺点 单例模式是一种设计模式#xff0c;用于确保一个类只有一个实例#xff0c;并提供一个全局的访问点来获取该实例。它常用于需要在整个应… 目录 饿汉式懒汉式双检查锁线程安全的版本什么是reorder解决内存读写reorder不安全方法代码解释懒汉式的优缺点 单例模式是一种设计模式用于确保一个类只有一个实例并提供一个全局的访问点来获取该实例。它常用于需要在整个应用程序中共享相同资源或状态的情况下。 单例模式分为饿汉式和懒汉式 饿汉式 在饿汉式中实例在类加载时就被初始化并且保证在多线程环境下的线程安全。 // 饿汉式 class Singleton { private:static Singleton* instance; // 静态成员变量保存实例指针Singleton() {} // 构造函数私有化Singleton(const Singleton other) {} // 拷贝构造函数私有化Singleton operator(const Singleton) {} // 赋值运算符私有化public:static Singleton* getInstance() {return instance;} };Singleton* Singleton::instance new Singleton(); // 在类加载时初始化实例// 使用示例 Singleton* obj1 Singleton::getInstance(); Singleton* obj2 Singleton::getInstance();// obj1 和 obj2 是同一个实例饿汉式下类的实例对象在类加载时就被创建并赋值给静态成员变量instance因此不需要考虑线程安全问题。因为每次调用getInstance方法都会返回同一个实例。 饿汉式的优点是实现简单线程安全缺点是无法实现延迟加载即类在加载时就创建好了实例可能会浪费资源。 懒汉式 懒汉式的实现方法是将实例的创建延迟到第一次请求访问时再进行初始化这样可以避免初始化时资源的浪费和额外的开销但需要考虑多线程之间的线程安全问题。 class Singleton { private:Singleton() {}Singleton(const Singleton other) {}Singleton operator(const Singleton) {} // 赋值运算符私有化 public:static Singleton* getInstance();static Singleton* Singleton::m_instance; };Singleton* Singleton::m_instance nullptr;// 线程不安全 Singleton* Singleton::getInstance() {if (m_instance nullptr)m_instance new Singleton();return m_instance; }在getInstance方法中我们先判断m_instance是否为空为空就new一个出来。但是这样在单线程下是安全的因为m_instance只会被创建一次在多线程下可能会被创建多次。 双检查锁线程安全的版本 class Singleton { private:Singleton() {}Singleton(const Singleton other) {}Singleton operator(const Singleton) {} // 赋值运算符私有化public:static Singleton* getInstance();static Singleton* m_instance;static std::mutex m_mutex; };Singleton* Singleton::m_instance nullptr; std::mutex m_mutex;// 多线程安全但锁的代价过高 Singleton* Singleton::getInstance() {std::lock_guardstd::mutex lock(m_mutex);if (m_instance nullptr)m_instance new Singleton();return m_instance; }这个版本在多线程下是安全的因为加锁了但是在读操作的情况下也就是如果m_instance直接返回时是不需要加锁的所以这个版本在高并发的情况下开销很大很耗时因为不管是写操作还是读操作都需要加锁减锁。 为了解决这个问题我们可以使用双检查锁来避免这样的开销问题 // 双检查锁但由于内存读写reorder不安全 Singleton* Singleton::getInstance() {if (m_instance nullptr){std::lock_guardstd::mutex lock(m_mutex);if (m_instance nullptr)m_instance new Singleton();}return m_instance; }锁前检查是否为空是为了避免读操作下还进行加锁锁后检查是为了避免多次创建。 但是这样还是有问题内存读写reorder不安全。 什么是reorder reorder就是在编译器底层进行优化重排指令的执行顺序。 举个例子 m_instance new Singleton(); 这行代码在编译器底层大致可以分为三个步骤 1、分配内存 2、调用构造器对内存进行初始化 3、将内存的地址赋值给m_instance 但在实际的运行过程中编译器执行的顺序可能是1-》3-》2这就会导致当多个线程同时调用getInstance方法并且m_instance为nullptr时它们可能会同时通过if语句的判断条件进入临界区。在这种情况下第一个线程通过了if语句的条件检查并在锁内部实例化了Singleton对象。但由于内存读写重排序的存在编译器或处理器可能会将Singleton对象的初始化操作重排到锁的外部这会导致第二个线程在第一个线程完成实例化之前通过了if语句的条件检查直接返回使用但此时m_instance还没有进行初始化。 解决内存读写reorder不安全方法 为了解决这个问题我们可以使用如下代码实现支持C11以上版本并跨平台 class Singleton { private:Singleton();Singleton(const Singleton other);public:static Singleton* getInstance();static std::atomicSingleton* m_instance;static std::mutex m_mutex; };std::atomicSingleton* Singleton::m_instance; std::mutex m_mutex;Singleton* Singleton::getInstance() {Singleton* tmp m_instance.load(std::memory_order_relaxed);std::atomic_thread_fence(std::memory_order_acquire);if (tmp nullptr){std::lock_guardstd::mutex lock(m_mutex);tmp m_instance.load(std::memory_order_relaxed);if (tmp nullptr){tmp new Singleton;std::atomic_thread_fence(std::memory_order_release);m_instance.store(tmp, std::memory_order_relaxed);}}return tmp; }代码解释 首先使用了双重检查锁定来提高性能。代码开始时通过调用 m_instance.load(std::memory_order_relaxed) 加载 m_instance 变量的值并将结果赋给 tmp 变量。 接下来通过调用 std::atomic_thread_fence(std::memory_order_acquire) 来添加内存屏障保证之前的读操作完成后之后的读写操作不会被重排序。 然后通过判断 tmp 是否为 nullptr来确定是否需要创建实例。如果 tmp 是 nullptr表示还没有创建实例需要进行创建。 在创建实例之前先获取一个互斥锁 m_mutex确保只有一个线程可以访问临界区代码。 再次检查 tmp 是否为 nullptr是为了防止多个线程同时通过第一个检查而进入临界区因为在第一个检查后可能已经有其他线程创建了实例。 在临界区内部首先创造了一个 Singleton 类的实例 tmp。然后通过 std::atomic_thread_fence(std::memory_order_release) 添加内存屏障确保在 tmp 赋值完成后该实例的构造函数中的其他写操作不会被重排序。 最后通过调用 m_instance.store(tmp, std::memory_order_relaxed) 将 tmp 存储到 m_instance 变量中。 在临界区外部返回已经创建的实例 tmp。 这种实现方式既兼顾了性能又保证了线程安全。通过使用双重检查锁定和互斥锁可以避免多个线程同时创建实例同时使用原子操作和内存屏障来保证实例的可见性和有序性。 懒汉式的优缺点 优点 1、延迟加载懒汉式在需要用到实例的时候才创建可以在程序启动时减少不必要的消耗。 2、节约内存懒汉式只会在用到对象时创建避免了无谓的内存占用。 缺点 1、线程安全性问题多线程下同时获取实例时可能会造成实例被多次创建的问题 2、性能问题在多线程环境下为了保证实例被唯一创建需要引入额外的同步开销高并发下会影响性能 3、实现复杂为了保证线程安全需要使用双检查锁等方法增加了代码的复杂性。
http://www.dnsts.com.cn/news/204872.html

相关文章:

  • 酒店网站模板设计方案网页游戏网游
  • myeclipse怎样做网站上海站优云网络科技有限公司
  • 做求职网站市场外贸自助建站哪个好
  • 湖南省建设厅安许审核公布网站wordpress .htaccess 伪静态
  • 海北州网站建设公司广州交易中心官网
  • 淮阴区城乡建设管理局网站微信报名小程序怎么做
  • html生成网站简单的视频制作软件推荐
  • 潍坊手机网站制作公众号和网站先做哪个
  • 建设网站只能是公司吗棋牌推广
  • 建站排名乔拓云建站平台
  • 凡科网网站后台建设自助建站编辑器
  • Seo自己做网站设计方案格式模板范文
  • 如何建设成为营销网站品牌建设和渠道建设哪个更重要
  • 课程网站建设毕业设计wordpress怎么添加音乐播放器
  • 114啦怎么建设网站金华手机网站建设
  • 谁有那种手机网站wordpress多用户小程序商城
  • 网站建设好弄吗西宁手机微网站
  • 网站如何绑定域名柳州网站推广最好的公司
  • 合肥浦发建设集团网站wordpress刷新按钮
  • 南宁网站推广策略外包网站设计
  • 集团网站建设制作费用南宁网络推广外包
  • wordpress标签添加内链插件营销网站seo推广费用
  • 本网站立足于海外服务器现在有什么网站可以做兼职的
  • 桐乡网站建设专业的深圳网站建设公司
  • 网站制作是不是要一个后台苏州网站建设建站网
  • 高效的宝安网站推广wordpress 注册页面
  • 北京网站制作的公司哪家好wordpress网易云课堂
  • 口碑好的扬中网站建设创业平台
  • 匿名聊天网站怎么做wordpress 主题单页
  • 滕州英文网站建设江西建设厅网站官网