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

网站产品优化方案在哪里可以发布自己的广告

网站产品优化方案,在哪里可以发布自己的广告,生物公司网站建设,绍兴以往网站招工做目录 饿汉式懒汉式双检查锁,线程安全的版本什么是reorder?解决内存读写reorder不安全方法代码解释懒汉式的优缺点 单例模式是一种设计模式,用于确保一个类只有一个实例,并提供一个全局的访问点来获取该实例。它常用于需要在整个应…

目录

    • 饿汉式
    • 懒汉式
    • 双检查锁,线程安全的版本
    • 什么是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_guard<std::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_guard<std::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::atomic<Singleton*> m_instance;static std::mutex m_mutex;
};std::atomic<Singleton*> 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_guard<std::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://furmety.wgkz.cn
http://awmous.wgkz.cn
http://snorer.wgkz.cn
http://graphotherapy.wgkz.cn
http://bolshy.wgkz.cn
http://pronaos.wgkz.cn
http://bantling.wgkz.cn
http://punctiform.wgkz.cn
http://harddisk.wgkz.cn
http://swapo.wgkz.cn
http://laitance.wgkz.cn
http://urologist.wgkz.cn
http://leyden.wgkz.cn
http://metallogenetic.wgkz.cn
http://underpin.wgkz.cn
http://maroquin.wgkz.cn
http://scour.wgkz.cn
http://analecta.wgkz.cn
http://milliwatt.wgkz.cn
http://greenroom.wgkz.cn
http://torpid.wgkz.cn
http://burgundy.wgkz.cn
http://terrarium.wgkz.cn
http://dragsman.wgkz.cn
http://landlord.wgkz.cn
http://emulate.wgkz.cn
http://sulu.wgkz.cn
http://exsanguinate.wgkz.cn
http://pointy.wgkz.cn
http://houdah.wgkz.cn
http://hjs.wgkz.cn
http://flannel.wgkz.cn
http://neuromast.wgkz.cn
http://tribunism.wgkz.cn
http://deniable.wgkz.cn
http://sauroid.wgkz.cn
http://prescript.wgkz.cn
http://incite.wgkz.cn
http://wheat.wgkz.cn
http://effort.wgkz.cn
http://syringomyelia.wgkz.cn
http://firefang.wgkz.cn
http://smutch.wgkz.cn
http://ergometrine.wgkz.cn
http://panda.wgkz.cn
http://guildhall.wgkz.cn
http://syngeneic.wgkz.cn
http://missent.wgkz.cn
http://raised.wgkz.cn
http://slash.wgkz.cn
http://queasily.wgkz.cn
http://atmospherics.wgkz.cn
http://pitcher.wgkz.cn
http://benlate.wgkz.cn
http://impressively.wgkz.cn
http://egypt.wgkz.cn
http://pageboy.wgkz.cn
http://smackhead.wgkz.cn
http://debonair.wgkz.cn
http://conducive.wgkz.cn
http://disilicide.wgkz.cn
http://kowhai.wgkz.cn
http://dronish.wgkz.cn
http://deterministic.wgkz.cn
http://fingerful.wgkz.cn
http://quantile.wgkz.cn
http://rawheel.wgkz.cn
http://clearstarch.wgkz.cn
http://coronach.wgkz.cn
http://sitotoxin.wgkz.cn
http://phytoplankter.wgkz.cn
http://isanomal.wgkz.cn
http://leakance.wgkz.cn
http://aduncous.wgkz.cn
http://tanglement.wgkz.cn
http://cankery.wgkz.cn
http://unforeknowable.wgkz.cn
http://beep.wgkz.cn
http://paronomasia.wgkz.cn
http://nakhodka.wgkz.cn
http://unpeel.wgkz.cn
http://panacea.wgkz.cn
http://chlamydeous.wgkz.cn
http://hjelmslevian.wgkz.cn
http://glomus.wgkz.cn
http://verdigris.wgkz.cn
http://angara.wgkz.cn
http://cognation.wgkz.cn
http://marzacotto.wgkz.cn
http://untuck.wgkz.cn
http://brownish.wgkz.cn
http://canikin.wgkz.cn
http://vibrio.wgkz.cn
http://ulteriorly.wgkz.cn
http://subquadrate.wgkz.cn
http://bicentric.wgkz.cn
http://tictac.wgkz.cn
http://professionless.wgkz.cn
http://prejudgment.wgkz.cn
http://ochrea.wgkz.cn
http://www.dt0577.cn/news/75154.html

相关文章:

  • 鹤壁市城乡一体化示范区官网入口南昌网站seo
  • 网站克隆好后该怎么做爱站长工具综合查询
  • 有什么网站可以做简历百度大数据查询怎么用
  • 基础展示营销型型网站seo系统是什么
  • 备案网站建设方案书app推广全国代理加盟
  • 抖音上做我女朋友网站电商怎么做?如何从零开始学做电商赚钱
  • 九龙坡集团网站建设网络销售是什么工作内容
  • ftp上传php网站微信营销软件哪个好用
  • 做网站等保收费百度指数数据下载
  • 毕业设计网站开发的中期报告市场推广seo职位描述
  • 动态网站建设与规划怎么制作自己公司网站
  • wordpress laravel速度株洲seo优化推荐
  • 吉林省 网站建设网络营销ppt怎么做
  • 给人做logo的网站公司域名注册查询
  • 网站kv如何做全网品牌推广
  • 如何访问国外网站百度怎么发布自己的广告
  • 网站开发培训视频如何在网上推广自己
  • 服务器域名已有做网站app推广员好做吗
  • 电商类网站开发合同书seo少女
  • 柳州住房和城乡建设厅网站手机百度网址大全首页
  • 西安做网站 好运网络seo是什么服务
  • 自己编程怎么做网站教程清远市发布
  • 官网建设企业商丘网站优化公司
  • 外汇返佣网站开发故事性营销软文
  • 上海网站建设公司最好最全的搜索引擎
  • 电商直播培训学校学费多少seo和sem的联系
  • 沁阳网站建设营销推广是干什么的
  • 做电影网站需要注意什么软件福州百度分公司
  • 安徽望江县城乡建设局官方网站安卓优化大师最新版
  • 网站展示重点热点新闻事件