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

手机微信小程序怎么制作佛山选择免费网站优化

手机微信小程序怎么制作,佛山选择免费网站优化,做720效果的还有哪个网站,wordpress支持的语言使用C无锁编程实现多线程下的单例模式 贺志国 2023.8.1 在多线程环境下创建一个类的单例对象#xff0c;要比单线程环境下要复杂很多。下面介绍在多线程环境下实现单例模式的几种方法。 一、尺寸较小的类单例对象创建 如果待创建的单例类SingletonForMultithread内包含的成…使用C无锁编程实现多线程下的单例模式 贺志国 2023.8.1 在多线程环境下创建一个类的单例对象要比单线程环境下要复杂很多。下面介绍在多线程环境下实现单例模式的几种方法。 一、尺寸较小的类单例对象创建 如果待创建的单例类SingletonForMultithread内包含的成员变量较少整个类占用的内存空间较小则可使用局部静态变量来创建单例对象。C 11标准保证在进入多线程前已完成静态类对象的构建。如果类的尺寸较大静态变量存储栈区无法容纳该类的单例对象则禁止使用该方法。例如64位Linux系统默认栈的最大空间为8 MB64位Windows系统默认栈的最大空间为1 MB当待创建的单例对象尺寸接近或超过上述栈的默认存储空间时如使用该方法创建则会导致程序崩溃。示例代码如下所示 class SmallSingletonForMultithread {public:static SmallSingletonForMultithread GetInstance() {static SmallSingletonForMultithread instance;return instance;}private:SmallSingletonForMultithread() default;~SmallSingletonForMultithread() default;SmallSingletonForMultithread(const SmallSingletonForMultithread) delete;SmallSingletonForMultithread operator(const SmallSingletonForMultithread) delete;SmallSingletonForMultithread(SmallSingletonForMultithread) delete;SmallSingletonForMultithread operator(SmallSingletonForMultithread) delete; };二、尺寸较大的类单例对象创建要求显式调用销毁函数来避免内存泄漏 在实际工作中由于某些单例类的尺寸较大静态变量存储栈区无法容纳该单例对象因此无法使用上述方法来创建单例对象这时需要使用new在堆区动态创建单例对象。为了避免多线程环境下对于单例对象的抢夺可使用C无锁编程来实现。需要付出的代价就是最后一个调用者需要显式地调用销毁函数DestoryInstance来避免内存泄漏示例代码如下所示 #include atomic #include cassert #include mutexclass SingletonForMultithread {public:static SingletonForMultithread* GetInstance() {if (!instance_.load(std::memory_order_acquire)) {auto* new_ptr new SingletonForMultithread;SingletonForMultithread* old_ptr nullptr;if (!instance_.compare_exchange_strong(old_ptr, new_ptr,std::memory_order_release,std::memory_order_relaxed)) {// If the CAS operation fails, another thread has created a singleton// object, and its necessary to delete the temporary object created by// the current thread.delete new_ptr;new_ptr nullptr;}}return instance_.load(std::memory_order_relaxed);}static void DestoryInstance() {if (instance_.load(std::memory_order_acquire)) {auto* old_ptr instance_.load(std::memory_order_relaxed);SingletonForMultithread* new_ptr nullptr;if (instance_.compare_exchange_strong(old_ptr, new_ptr,std::memory_order_release,std::memory_order_relaxed)) {// If the CAS operation succeeds, the current thread obtains the// original object and can safely delete it.delete old_ptr;old_ptr nullptr;}}}private:SingletonForMultithread() default;~SingletonForMultithread() default;SingletonForMultithread(const SingletonForMultithread) delete;SingletonForMultithread operator(const SingletonForMultithread) delete;SingletonForMultithread(SingletonForMultithread) delete;SingletonForMultithread operator(SingletonForMultithread) delete;private:static std::atomicSingletonForMultithread* instance_; };// Static member variable initialization std::atomicSingletonForMultithread* SingletonForMultithread::instance_;int main() {auto* singleton SingletonForMultithread::GetInstance();assert(singleton ! nullptr);singleton-DestoryInstance();return 0; }三、尺寸较大的类单例对象创建使用std::unique_ptrT和std::call_once实现 很多时候我们无法显式地调用销毁函数来避免内存泄漏这时就可借助std::unique_ptrT和std::call_once来实现示例代码如下 #include cassert #include memory #include mutexclass SingletonForMultithread {public:~SingletonForMultithread() default;static SingletonForMultithread* GetInstance() {static std::unique_ptrSingletonForMultithread instance;static std::once_flag only_once;std::call_once(only_once,[]() { instance.reset(new (std::nothrow) SingletonForMultithread); });return instance.get();}private:SingletonForMultithread() default;SingletonForMultithread(const SingletonForMultithread) delete;SingletonForMultithread operator(const SingletonForMultithread) delete;SingletonForMultithread(SingletonForMultithread) delete;SingletonForMultithread operator(SingletonForMultithread) delete; };int main() {auto* singleton SingletonForMultithread::GetInstance();assert(singleton ! nullptr);return 0; }但我在Ubuntu 20.04系统上使用GCC 9.4.0似乎无法正常完成任务会抛出异常产生core dump原因暂不详。 四、尺寸较大的类单例对象创建使用std::unique_ptrT和std::atomic_flag实现 第三节借助std::unique_ptrT和std::call_once来实现单例对象的创建同时避免显式地调用销毁函数来避免内存泄漏。这种方法在Ubuntu 20.04系统上使用GCC 9.4.0实现时似乎会导致程序core dump。于是我们使用std::atomic_flag替换std::call_once来完成任务。基本思想如下首先定义一个静态的无锁标志变量std::atomic_flag start_flag并将其初始值设置为ATOMIC_FLAG_INIT。第一次调用start_flag.test_and_set(std::memory_order_relaxed)函数时由于start_flag的状态是ATOMIC_FLAG_INIT该函数返回false于是可调用instance.reset(new SingletonForMultithread)创建单例对象。第二次直至第N次调用start_flag.test_and_set(std::memory_order_relaxed)函数时因为start_flag的状态已被设置该函数返回true创建单例对象的语句instance.reset(new SingletonForMultithread)永远不会被再次执行这就达到了只创建一次的目的。同时因为使用静态的智能指针变量std::unique_ptrSingletonForMultithread instance来管理单例对象于是不再需要显式地回收内存只要程序结束静态变量自动清除智能指针对象instance会在其析构函数中释放内存。 由于new运算符创建单例对象可能耗时较长为了避免其他线程在单例对象创建到一半的过程中读取到不完整的对象导致未定义的行为我们使用另一个原子变量std::atomicbool finished来确保创建动作已正确完成不选用另一个无锁标志变量std::atomic_flag的原因是该类在C 20标准前未提供单独的测试函数test。finished.store(true, std::memory_order_release);与while (!finished.load(std::memory_order_acquire))的内存顺序实现了synchronizes-with与happens-before关系保证在while (!finished.load(std::memory_order_acquire))成功时instance.reset(new SingletonForMultithread);必定执行完毕单例对象的创建是完整的。 完整的示例代码如下 #include atomic #include cassert #include memory #include mutex #include thread #include vectorusing namespace std::chrono_literals;namespace { constexpr size_t kThreadNum 2000; }class SingletonForMultithread {public:~SingletonForMultithread() default;static SingletonForMultithread* GetInstance() {static std::unique_ptrSingletonForMultithread instance;static std::atomic_flag start_flag ATOMIC_FLAG_INIT;static std::atomicbool finished(false);if (!start_flag.test_and_set(std::memory_order_relaxed)) {// The object created by the new operator may be relatively large and// time-consuming, therefore another atomic variable finished is used to// ensure that other threads read a fully constructed singleton object. Do// not consider using another std::atomic_flag. Because it doesnt// provide a separate test function before the C 20 standard.instance.reset(new (std::nothrow) SingletonForMultithread);finished.store(true, std::memory_order_release);}// Wait in a loop until the singleton object is fully created, using// std::this_thread::yield() to save CPU resources.while (!finished.load(std::memory_order_acquire)) {std::this_thread::yield();}return instance.get();}private:SingletonForMultithread() {// Simulate a constructor that takes a relative long time.std::this_thread::sleep_for(10ms);}SingletonForMultithread(const SingletonForMultithread) delete;SingletonForMultithread operator(const SingletonForMultithread) delete;SingletonForMultithread(SingletonForMultithread) delete;SingletonForMultithread operator(SingletonForMultithread) delete; };int main() {std::vectorstd::thread customers;for (size_t i 0; i kThreadNum; i) {customers.emplace_back(SingletonForMultithread::GetInstance);}for (size_t i 0; i kThreadNum; i) {customers[i].join();}auto* singleton SingletonForMultithread::GetInstance();assert(singleton ! nullptr);return 0; }
http://www.tj-hxxt.cn/news/136397.html

相关文章:

  • 做设计的网站有哪些手机家装绘图软件
  • 做外贸搜索外国客户的网站淘宝网站SEO怎么做
  • 加强公司网站建设及数据库的通知代理网络怎么关闭
  • 新浪网站源代码网站后台管理图片
  • pc网站建设和推广简单的网站怎样做
  • 备份wordpress网站品牌网络推广方式
  • 做网站创业风险分析网站ping值
  • thinkphp怎么做网站cms开源建站系统
  • 上海市建设工程材料网站黄金网站软件入口免费
  • 广东圆心科技网站开发建站教程详解cms 导航网站
  • 建网站都用什么字体连云港市连云区建设局网站
  • 做有支付系统的网站一般需要多少钱创业找项目
  • 网站建设金手指快速wordpress加载
  • 济南学生网站建设求职域名备案需要有网站吗
  • 搭建网站 优帮云搜索引擎优化简称seo
  • 女生做网站后期维护工作好吗公司体系建设的意义
  • 网站建设网页制网站建设彩票网
  • zz手表网站公司想建一个网站找谁做
  • 网站建设安全性指标搭建一个商城类网站
  • wordpress 图站队徽logo在线设计
  • 公司建设网站需要什么资质昆山规划建设局网站
  • 上海网站建设最佳方案合击版手游带月灵
  • 北京cms建站模板wordpress 图床插件
  • 建站优化易下拉系统网络营销有哪些方式
  • 小程序开发教程画画优化型网站模板
  • 修改网站空间服务器密码班级优化大师app
  • 东莞个人网站建设企业展厅建筑
  • 镇江地区做网站的公司有哪些青秀网站建设
  • 合肥网站建设托管黑色大气金融投资企业网站模板
  • 深圳网站建设 猴王网络怎么创建属于自己的网站