想开个网站不知怎样做,南京有名的网站建设公司,seo技术中心,网站开发软件怎么做提示#xff1a;文章写完后#xff0c;目录可以自动生成#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、单例是什么#xff1f;二、解读1.懒汉式2.饿汉式3.static变量特性4.call_once特性 总结 前言
单例模式几乎是每种语言都不可少的一种设计模式#xff0c… 提示文章写完后目录可以自动生成如何生成可参考右边的帮助文档 文章目录 前言一、单例是什么二、解读1.懒汉式2.饿汉式3.static变量特性4.call_once特性 总结 前言
单例模式几乎是每种语言都不可少的一种设计模式今天就针对C语言来解读下集中单例模式并给出代码说明。 一、单例是什么
单例就是单实例简而言之内存中只存在这一个实例在很多场景下很有用比如线程池、内存池等等。
二、解读
按照创建时机可以分为饿汉式和懒汉式。所谓饿汉式就是程序启动的时候立即创建饿汉式就是需要的时候创建。
1.懒汉式
懒汉式顾名思义不会主动创建直到主动获取才创建。懒汉式又主要分为两种线程安全和线程不安全。接下来分别介绍这几种和提供源代码示例。
简单模式:
class Singleton {static Singleton *getInstance() {if (instance nullptr) {instance new Singleton();}return instance;}private:static Singleton *instance;};Singleton *Singleton::instance nullptr;优点性能和饿汉式差不多没有锁性能不会损失 缺点线程不安全 总结需要自己确保线程安全比如启动线程前就要创建好避免竞争条件产生
线程安全
#include mutex
class Singleton {public:static Singleton *getInstance() {std::lock_guardstd::mutex lock(mtx);if (instance nullptr) {instance new Singleton();}return instance;}private:static Singleton *instance;static std::mutex mtx;};Singleton *Singleton::instance nullptr;std::mutex Singleton::mtx;优点线程安全随时随地都是安全的 缺点性能差每次获取实例都要上锁 总结不建议使用
双重检查锁
#include mutex
class Singleton {public:static Singleton *getInstance() {if (instance nullptr) {std::lock_guardstd::mutex lock(mtx);if (instance nullptr) {instance new Singleton();}}return instance;}private:static Singleton *instance;static std::mutex mtx;};Singleton *Singleton::instance nullptr;std::mutex Singleton::mtx;优点线程安全性能比上面的强 缺点性能有轻微损耗只有第一次创建才需要上锁后面访问不需要上锁 总结强烈推荐既解决了线程安全问题又解决了性能问题
2.饿汉式
不会产生数据竞争程序启动时就创建和在竞争条件出现之前创建完成所以先天是线程安全的。
class Singleton {public:static Singleton getInstance() {return instance;}private:static Singleton instance;};Singleton Singleton::instance;优点线程安全性能最好 缺点无论需不需要都会创建会浪费资源 总结可用但不太推荐
3.static变量特性
C11之后static修饰的局部变量有一个很重要的特性初始化的时候会自动加锁这个特性是编译器负责维护的。所以可以借用这个特性开发一个单例模式一定是线程安全的而且提供不俗的性能。
注这个单例又叫米尔斯单例(Meyers Singleton)
class Singleton {public:static Singleton getInstance() {static Singleton instance;return instance;}private:Singleton() {}public:Singleton(const Singleton ) delete;Singleton operator(const Singleton ) delete;};优点线程安全性能不俗 缺点初始化上锁略微拖慢性能后面正常获取C11以后版本才行 总结极其推荐
4.call_once特性
除了米尔斯单例还有一个C11的新特性可以设计单例这个特性我们平常容易忽视那就是call_once。它也是一种线程同步机制C保证call_once保护的方法只被调用一次。
#include atomic
class Singleton {public:static Singleton getInstance(){std::call_once(flag,[]{instance new Singleton();});return *instance;}private:static Singleton* instance;static std::once_flag flag;};Singleton* Singleton::instance nullptr;std::once_flag Singleton::flag;优点线程安全性能不俗针对方法可以同时初始化多个资源 缺点第一次调用拖慢性能后面就不会了C11以后版本才行 总结和米尔斯很像但是实现比米尔斯复杂推荐指数放在米尔斯单例之后 总结
1、C11以上版本优先使用米尔斯单例比双重检查锁性能强 2、其他场景建议双重检查锁call_once酌情使用