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

外贸网站怎么做关键词设计本笔记本

外贸网站怎么做关键词,设计本笔记本,青岛建站费用,施工企业资质分为哪些文章目录 引言简介起航#xff01;向“确保某个类在系统中只有一个实例”进发 ⛵️Lazy SingletonDouble-checked locking#xff08;DCL#xff09; SingletonVolatile SingletonAtomic SingletonMeyers Singleton 附#xff1a;C静态对象的初始化 引言 说起单例模式向“确保某个类在系统中只有一个实例”进发 ⛵️Lazy SingletonDouble-checked lockingDCL SingletonVolatile SingletonAtomic SingletonMeyers Singleton 附C静态对象的初始化 引言 说起单例模式我想即便屏幕前的你此前没有系统学习过设计模式也应该听说过它的大名。 但是这篇文章的重点不是去聊这个模式在实际生产过程中怎么用而是想聊一下这个模式发展的历史。如果你的目的是想了解其具体用法你可以在检索一下其他人写的总结再往下看的话可能不会有你想要的答案。 简介 在软件系统中经常有一些特殊的类必须保证它们在系统中只存在一个实例才能确保它们的逻辑正确性以及良好的效率。 单例模式是一种设计模式其核心目的是确保某个类在系统中只有一个实例并提供一个全局访问点来访问这个实例。 “确保某个类在系统中只有一个实例”——这个目的听起来似乎很简单不要觉得荒谬某些特定的情况下我们的系统中确实只需要某个类的一个实例就可以了这样既能满足实际使用场景又能减少内存开销避免资源的多重占用提升性能。 倘若我们从这个目的出发——“确保某个类在系统中只有一个实例”现在的任务就是设计某种手段以达到我们的目的。 起航向“确保某个类在系统中只有一个实例”进发 ⛵️ 也许刚看到这个目标的时候你会有点疑惑这不是很简单吗既然你想要确保系统中只有一个某个类的对象那我就只创建一个对象不就好了吗 听起来好像没错但是“确保某个类在系统中只有一个实例”这应该是类设计者的责任而不是使用者的责任。 现在让我们从类设计者的角度重新审视这个问题。 我们知道创建类的实例——这个动作是借由类的构造函数完成的换句话说我们可以确定问题的突破点是在构造函数身上。那么如何绕过常规的构造器提供一种机制来保证一个类只有一个实例呢 首先我们先解决构造函数的权限问题。C中的权限说起来一共有三种publicprotectprivate。而无论对于用户还是派生类来讲真正的权限事实上只有两种 对于用户而言public权限是可访问的private权限和protect权限是不可访问的对于派生类而言private是不可访问的protect与public是可访问的 而如果将这个类的构造函数用public去修饰意味着用户可以随意创建对象“创建对象”这个动作无法受到我们的管控因此如果想要限制用户“不那么自由”的创建实例我们应当将构造函数声明为private class Singleton{private:Singleton();//私有构造函数static Singleton* m_instance;public:static Singleton* getInstance();//全局访问点 } Singleton* Singleton::m_instance NULL;Lazy Singleton 那么如何“确保某个类在系统中只有一个实例”很容易想到 1 Singleton* Singleton::getInstance(){ 2 if(m_instance nullptr){ 3 m_instance new Singleton(); 4 } 5 return m_instance; 6 }懒汉版Lazy Singleton单例实例在第一次被使用时才进行初始化这叫做延迟初始化也叫做懒加载。 Lazy Singleton存在内存泄露的问题这里有两种解决方法 使用智能指针使用静态的嵌套类对象 对于第二种解决方法代码如下 // version 1.1 class Singleton { private:static Singleton* instance; private:Singleton() { };~Singleton() { };Singleton(const Singleton);Singleton operator(const Singleton); private:class Deletor {public:~Deletor() {if(Singleton::instance ! NULL)delete Singleton::instance;}};static Deletor deletor; public:static Singleton* getInstance() {if(instance NULL) {instance new Singleton();}return instance;} };// init static member Singleton* Singleton::instance NULL;在程序运行结束时系统会调用静态成员deletor的析构函数该析构函数会删除单例的唯一实例。使用这种方法释放单例对象有以下特征 在单例类内部定义专有的嵌套类。在单例类内定义私有的专门用于释放的静态成员。利用程序在结束时析构全局变量的特性选择最终的释放时机。 这是一个简单的实现版本”有条件“ 的完成了我们的目标因为这个版本只能针对于单线程下的程序是个“线程非安全”版本一旦线程数大于1这个版本将不再起作用。 假设现在有两个线程thread A与thread B。 thread A 执行完第2行还没来得及执行第3行时thread B 抢到了时间片由于此时的m_instance仍为空因此thread也能进入if分支然后m_instance就被创建了两次。 有没有什么办法能够快速修复这个“bug“呢 Double-checked lockingDCL Singleton 很自然的你会想到加锁 1 Singleton* Singleton::getInstance(){ 2 Lock lock 3 if(m_instance nullptr){ 4 m_instance new Singleton(); 5 } 6 return m_instance; 7 }如你所愿我们在这个版本里加了一个锁再遇到上述场景时由于thread A抢到了锁并且还没释放因此thread A能正常创建实例并且当thread A出了函数体释放了锁之后thread B 进入函数体由于此时m_instance已经被创建因此并不会被创建两次。 问题解决了吗 按照上面的分析好像是的。但是你有没有注意到当实例已经被创建后的场景 假设实例m_instance已经被创建在之后的场景中程序再次进入该函数时都会先创建锁然后判断m_instance是否为空然后返回。每次进入函数体都会创建锁但是这个锁只有第一次才有真正的作用之后都是在浪费资源。 这个版本能够保证线程安全但是锁的代价过高。 还有没有改进版本呢 于是双检查锁版本诞生了 1 Singleton* Singleton::getInstance(){ 2 if(m_instance nullptr){ 3 Lock lock 基于作用域的加锁超出作用域自动调用析构函数解锁 4 if(m_instance nullptr){ 5 m_instance new Singleton(); 6 } 7 } 8 return m_instance; 9 }之前的版本是不管三七二十一都加锁现在的版本是进入函数体之后先问一次m_instance是不是空根据结果去决定是否加锁。规避了上一个版本锁的代价过高的问题。 有的小伙伴可能会在这里犯迷糊认为第二个if分支没有必要即可以删去第4行。 事实上如果删去了第4行那么情况就会变得跟第一个版本一模一样只要线程能同时通过第2行的检查那么这个实例就有被创建多次的可能。就算此时加了这个锁无非也就是多等一会儿没有其他作用。 这个版本看起来很完美问题似乎已经被我们解决了 但是我要告诉你这个版本在很长一段时间内迷惑了很多人包括一些专家都认为这个版本已经达到目标了。直到2000年左右Java领域的某些研究者才发现有问题而且很快在几乎所有的语言领域都发现这种实现有漏洞。由于内存读写reorder不安全会导致双检查锁失效。 怎么样的一个失效问题呢 让我们将目光聚焦到这行代码上 m_instance new Singleton();这行代码最终会被编译器编译成一段指令序列线程是在指令层次抢时间片的。但是这个指令有时候跟我们的假设不一样。 比如上面那行代码通常情况下到了指令层次之后可以划分为三个动作 分配一片内存在这片内存上执行初始化操作将得到的内存地址赋值给m_instance 是这三个动作没错但是到了指令层面之后它们的顺序却可能由于编译器优化而被打乱成下面这样 分配一片内存将最后得到的内存地址赋值给m_instance在这片内存上执行初始化操作 看到了吗第二步和第三步的顺序可能会被颠倒 1 Singleton* Singleton::getInstance(){ 2 if(m_instance nullptr){ 3 Lock lock 4 if(m_instance nullptr){ 5 m_instance new Singleton(); 6 } 7 } 8 return m_instance; 9 }现在再次回到之前的场景假设有两个threadthread A执行第5步之后由于编译器优化而执行了 分配一片内存将最后得到的内存地址赋值给m_instance 第三步还没来得及执行时间片就被thread B抢走了由于此时m_instance已经被赋予了地址因此m_instance不再为空当thread B再次进入函数体之后由于第2步判断m_instance是否为空的结果为false导致被直接返回。而事实上m_instance并没有完成初始化操作此时还不能使用。 当这个问题被发现后由于是编译器优化导致了此类问题的出现于是人们敦促编译器厂商给出问题解决方案。 Volatile Singleton 反过来想想编译器优化的目的是提升程序性能只是不巧导致了这个问题的出现如果为了一个单例模式的实现直接禁止这种优化属实有点说不过去。这个时候java和C#就很聪明在各自的语言中加了一个关键字Volatile其作用也很直截了当禁止指令重排。 C呢Visual C嫌标准委员会动作太慢2005年左右在自家编译器里也加入了volatile关键字但是由于是个人行为很显然不能跨平台。之后C11正式将volatile作为关键字纳入标准 class Singleton { public: static Singleton* instance() { if (pInstance 0) { Lock lock; if (pInstance 0) { pInstance new Singleton; } } return pInstance; } private: static Singleton * volatile pInstance; Singleton(){ } }; volatile这个关键字有两层语义 第一层语义是可见性。可见性指的是在一个线程中对该变量的修改会马上由工作内存Work Memory写回主内存Main Memory所以会马上反应在其它线程的读取操作中即看到的都是最新的结果。 第二层语义是禁止指令重排序优化。我们写的代码尤其是多线程代码由于编译器优化在实际执行的时候可能与我们编写的顺序不同。 Atomic Singleton 另外在C11 将原子操作纳入了标准我们可以通过标准提供的原子操作来处理该问题。 通过给原子变量设置 std::std::memory_order_xxx 来防止 CPU 的指令重排操作。 //C11版本之后的跨平台实现volatilestd::atomicSingleton* Singleton::m_instance; std::mutex Singleton::m_mutex;Singleton* Singleton::getInstance(){Singleton* tmp m_instance.load(std::memory_order_relaxed);std::atomic_thread_fence(std::memory_order_acquire);//获取内存fenceif(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_relaced);//释放内存fencem_instance.store(tmp,std::memory_order_relaxed);}}return tmp; }Meyers Singleton 《Effective C》的作者Meyer在Effective C3rd Item4中提出了一种到目前为止最简洁高效的解决方案 templatetypename T class Singleton { public:static T getInstance(){static T value;return value;}private:Singleton();~Singleton(); };非常优雅的一种实现。 先说结论 单线程下正确。C11及以后的版本如C14的多线程下正确。C11之前的多线程下不一定正确。 原因在于在C11之前的标准中并没有规定local static变量的内存模型所以很多编译器在实现local static变量的时候仅仅是进行了一次check参考《深入探索C对象模型》于是getInstance函数被编译器改写成这样了 bool initialized false; char value[sizeof(T)];T getInstance() {if (!initialized){initialized true;new (value) T();}return *(reinterpret_castT*(value)); }于是乎它就是不是线程安全的了。 但是在C11却是线程安全的这是因为新的C标准规定了当一个线程正在初始化一个变量的时候其他线程必须得等到该初始化完成以后才能访问它。 附C静态对象的初始化 non-local static对象函数外 C规定non-local static 对象的初始化发生在main函数执行之前也即main函数之前的单线程启动阶段所以不存在线程安全问题。但C没有规定多个non-local static 对象的初始化顺序尤其是来自多个编译单元的non-local static对象他们的初始化顺序是随机的。 local static 对象函数内 对于local static 对象其初始化发生在控制流第一次执行到该对象的初始化语句时。多个线程的控制流可能同时到达其初始化语句。 在C11之前在多线程环境下local static对象的初始化并不是线程安全的。具体表现就是如果一个线程正在执行local static对象的初始化语句但还没有完成初始化此时若其它线程也执行到该语句那么这个线程会认为自己是第一次执行该语句并进入该local static对象的构造函数中。这会造成这个local static对象的重复构造进而产生内存泄露问题。所以local static对象在多线程环境下的重复构造问题是需要解决的。 而C11则在语言规范中解决了这个问题。C11规定在一个线程开始local static 对象的初始化后到完成初始化前其他线程执行到这个local static对象的初始化语句就会等待直到该local static 对象初始化完成。
文章转载自:
http://www.morning.bqpgq.cn.gov.cn.bqpgq.cn
http://www.morning.rwzmz.cn.gov.cn.rwzmz.cn
http://www.morning.bfrsr.cn.gov.cn.bfrsr.cn
http://www.morning.qbgff.cn.gov.cn.qbgff.cn
http://www.morning.wwthz.cn.gov.cn.wwthz.cn
http://www.morning.gbxxh.cn.gov.cn.gbxxh.cn
http://www.morning.nfpct.cn.gov.cn.nfpct.cn
http://www.morning.skdrp.cn.gov.cn.skdrp.cn
http://www.morning.ktfbl.cn.gov.cn.ktfbl.cn
http://www.morning.pcwzb.cn.gov.cn.pcwzb.cn
http://www.morning.tqrbl.cn.gov.cn.tqrbl.cn
http://www.morning.rpkg.cn.gov.cn.rpkg.cn
http://www.morning.ayftwl.cn.gov.cn.ayftwl.cn
http://www.morning.rtkgc.cn.gov.cn.rtkgc.cn
http://www.morning.pangucheng.cn.gov.cn.pangucheng.cn
http://www.morning.cpmfp.cn.gov.cn.cpmfp.cn
http://www.morning.zylzk.cn.gov.cn.zylzk.cn
http://www.morning.lkbyj.cn.gov.cn.lkbyj.cn
http://www.morning.pwppk.cn.gov.cn.pwppk.cn
http://www.morning.mhfbp.cn.gov.cn.mhfbp.cn
http://www.morning.qkrz.cn.gov.cn.qkrz.cn
http://www.morning.dfffm.cn.gov.cn.dfffm.cn
http://www.morning.xqqcq.cn.gov.cn.xqqcq.cn
http://www.morning.hrzky.cn.gov.cn.hrzky.cn
http://www.morning.qyhcg.cn.gov.cn.qyhcg.cn
http://www.morning.mstrb.cn.gov.cn.mstrb.cn
http://www.morning.fjglf.cn.gov.cn.fjglf.cn
http://www.morning.dwgcx.cn.gov.cn.dwgcx.cn
http://www.morning.jjzxn.cn.gov.cn.jjzxn.cn
http://www.morning.lfqtp.cn.gov.cn.lfqtp.cn
http://www.morning.zqzhd.cn.gov.cn.zqzhd.cn
http://www.morning.fllfc.cn.gov.cn.fllfc.cn
http://www.morning.zzfqn.cn.gov.cn.zzfqn.cn
http://www.morning.nwczt.cn.gov.cn.nwczt.cn
http://www.morning.dyzbt.cn.gov.cn.dyzbt.cn
http://www.morning.ytmx.cn.gov.cn.ytmx.cn
http://www.morning.wpqcj.cn.gov.cn.wpqcj.cn
http://www.morning.qhqgk.cn.gov.cn.qhqgk.cn
http://www.morning.qxltp.cn.gov.cn.qxltp.cn
http://www.morning.yccnj.cn.gov.cn.yccnj.cn
http://www.morning.xlclj.cn.gov.cn.xlclj.cn
http://www.morning.rqqmd.cn.gov.cn.rqqmd.cn
http://www.morning.byjwl.cn.gov.cn.byjwl.cn
http://www.morning.srtw.cn.gov.cn.srtw.cn
http://www.morning.fpxsd.cn.gov.cn.fpxsd.cn
http://www.morning.yqkxr.cn.gov.cn.yqkxr.cn
http://www.morning.wngpq.cn.gov.cn.wngpq.cn
http://www.morning.hnpkr.cn.gov.cn.hnpkr.cn
http://www.morning.jlboyuan.cn.gov.cn.jlboyuan.cn
http://www.morning.kxqfz.cn.gov.cn.kxqfz.cn
http://www.morning.ptmsk.cn.gov.cn.ptmsk.cn
http://www.morning.hpdpp.cn.gov.cn.hpdpp.cn
http://www.morning.wjrq.cn.gov.cn.wjrq.cn
http://www.morning.skscy.cn.gov.cn.skscy.cn
http://www.morning.clccg.cn.gov.cn.clccg.cn
http://www.morning.tlfzp.cn.gov.cn.tlfzp.cn
http://www.morning.bzjpn.cn.gov.cn.bzjpn.cn
http://www.morning.pzrpz.cn.gov.cn.pzrpz.cn
http://www.morning.jyzqn.cn.gov.cn.jyzqn.cn
http://www.morning.ddgl.com.cn.gov.cn.ddgl.com.cn
http://www.morning.fygbq.cn.gov.cn.fygbq.cn
http://www.morning.rdtp.cn.gov.cn.rdtp.cn
http://www.morning.c7630.cn.gov.cn.c7630.cn
http://www.morning.ghlyy.cn.gov.cn.ghlyy.cn
http://www.morning.rkfh.cn.gov.cn.rkfh.cn
http://www.morning.mnqg.cn.gov.cn.mnqg.cn
http://www.morning.zhoer.com.gov.cn.zhoer.com
http://www.morning.ybnps.cn.gov.cn.ybnps.cn
http://www.morning.wmmqf.cn.gov.cn.wmmqf.cn
http://www.morning.fqyqm.cn.gov.cn.fqyqm.cn
http://www.morning.dshxj.cn.gov.cn.dshxj.cn
http://www.morning.xbrxk.cn.gov.cn.xbrxk.cn
http://www.morning.ailvturv.com.gov.cn.ailvturv.com
http://www.morning.trnl.cn.gov.cn.trnl.cn
http://www.morning.qcztm.cn.gov.cn.qcztm.cn
http://www.morning.hhboyus.cn.gov.cn.hhboyus.cn
http://www.morning.pzjrm.cn.gov.cn.pzjrm.cn
http://www.morning.wzdjl.cn.gov.cn.wzdjl.cn
http://www.morning.mwpcp.cn.gov.cn.mwpcp.cn
http://www.morning.xmhpq.cn.gov.cn.xmhpq.cn
http://www.tj-hxxt.cn/news/264757.html

相关文章:

  • 淘宝网站建设方案毕业设计客户关系管理的定义
  • 西宁整站优化旅游商城网站模板免费下载
  • 二维码制作网站有哪些河北省做网站的企业
  • wordpress建站好用吗东莞网站公司排名
  • 哪些行业做网站最重要国外做二手服装网站有哪些问题
  • 介绍常见的网络营销方式seo投放
  • 网站建设代码题手表网站建设
  • 网站建设需要什么知识网站流量运营
  • 网站建设售后培训php网站建设论文
  • 网站建设cms系统如何填写网站开发验收单
  • 购物网站建设 费用潍坊 网站推广
  • 纵横天下网站开发做网站运营难吗
  • 网站制作怎样做杭州百度快速排名提升
  • 网站改版 如何改版网站你懂我意思正能量免费
  • 做餐饮如何加入外卖网站郑州外贸营销网站建设
  • c 还可以做网站舆情app免费
  • p9制作公司天津网站优化公司哪家好
  • 网站开发公司经营范围织梦仿站
  • 广州建网站比较有名的公司天津有哪些好的做网站公司
  • 保定网站建设多少钱哪家好有没有网站做胡兼职
  • 提升网站转化率做试管网站
  • 网站建设asp编程网站建设模板推广
  • 任务平台网站建设成都景观设计公司
  • wordpress 导航站网站推荐几个免费的
  • 自己做的导航网站做直播网站要多少钱
  • 如何建外贸网站手机端网站自动弹出营销qq
  • 网站做app的软件叫什么一个网站的预算
  • 网站关键词抓取汇天网络科技有限公司
  • 中国十大摄影网站排名网站建设费用用
  • 使用joomla的网站wordpress会话过期