工程设计公司发展规划,北京朝阳区优化,发软文在哪个网站找文章最好,兰州有做百度网站的吗C11并发与多线程笔记#xff08;7#xff09; 单例设计模式共享数据分析、解决#xff0c;call_once 1.设计模式2.单例设计模式#xff1a;3.单例设计模式共享数据分析、解决4.std::call_once()#xff1a; 1.设计模式
程序灵活#xff0c;维护起来可能方便#xff0c;… C11并发与多线程笔记7 单例设计模式共享数据分析、解决call_once 1.设计模式2.单例设计模式3.单例设计模式共享数据分析、解决4.std::call_once() 1.设计模式
程序灵活维护起来可能方便用设计模式理念写出来的代码很晦涩但是别人接管、阅读代码都会很痛苦老外应付特别大的项目时把项目的开发经验、模块划分经验总结整理成设计模式中国零几年设计模式刚开始火时总喜欢拿一个设计模式往上套导致一个小小的项目总要加几个设计模式本末倒置设计模式有其独特的优点要活学活用不要深陷其中生搬硬套
2.单例设计模式
整个项目中有某个或者某些特殊的类只能创建一个属于该类的对象。 单例类只能生成一个对象。
# includeiostream
using namespace std;
class MyClass {//单例类
private:MyClass(){}//私有化构造函数static MyClass* m_instance;//静态成员变量
public:static MyClass* getInstance() {//静态成员函数用于创建对象if (m_instance NULL) {m_instance new MyClass();}return m_instance;}void func() {cout 测试 endl;}};
MyClass* MyClass::m_instance NULL;//类内定义类外初始化int main() {//创建一个对象返回该类Myclass对象的指针MyClass* p_a MyClass::getInstance();p_a-func();//测试
}如果觉得在单例模式new了一个对象而没有自己delete掉这样不合理。可以增加一个类中类CGarhuishounew一个单例类时创建一个静态的CGarhuishou对象这样在程序结束时会调用CGarhuishou的析构函数释放掉new出来的单例对象。
# includeiostream
using namespace std;
class MyClass {//单例类
private:MyClass(){}//私有化构造函数static MyClass* m_instance;//静态成员变量
public:static MyClass* getInstance() {//静态成员函数用于创建对象if (m_instance NULL) {m_instance new MyClass();static CGarhuishou cl; //释放对象}return m_instance;}class CGarhuishou {//类中套类用来释放对象public:~CGarhuishou() {if (MyClass::m_instance) {delete MyClass::m_instance;MyClass::m_instance NULL;}}};void func() {cout 测试 endl;}};
MyClass* MyClass::m_instance NULL;//类内定义类外初始化int main() {//创建一个对象返回该类Myclass对象的指针MyClass* p_a MyClass::getInstance();p_a-func();//测试
}3.单例设计模式共享数据分析、解决
面临问题需要在自己创建的线程而不是主线程中来创建单例类的对象这种线程可能不止一个。我们可能面临getInstance()这种成员函数需要互斥。 解决方法可以在加锁前判断m_instance是否为空否则每次调用MyClass::getInstance()都要加锁十分影响效率。
# includeiostream
# includethread
#includemutex
using namespace std;
mutex mutex1;
class MyClass {//单例类
private:MyClass(){}//私有化构造函数static MyClass* m_instance;//静态成员变量
public:static MyClass* getInstance() {//双重锁定 提高效率if (m_instance NULL) {unique_lockmutex myMutex(mutex1);//单独加此代码每一次判断创建新对象都要加锁if (m_instance NULL) {m_instance new MyClass();static CGarhuishou cl;}}return m_instance;}class CGarhuishou {//类中套类用来释放对象public:~CGarhuishou() {if (MyClass::m_instance) {delete MyClass::m_instance;MyClass::m_instance NULL;}}};void func() {cout 测试 endl;}
};
MyClass* MyClass::m_instance NULL;//类内定义类外初始化//线程入口函数
void mythread() {cout myPrint线程开始执行了 endl;MyClass* p_a MyClass::getInstance();cout myPrint线程结束执行了 endl;
}
int main() {thread myobj1(mythread);thread myobj2(mythread);myobj1.join();myobj2.join();
}4.std::call_once()
函数模板该函数的第一个参数为标记第二个参数是一个函数名如a()。 功能能够保证函数a()只被调用一次。具备互斥量的能力而且比互斥量消耗的资源更少更高效。 call_once()需要与一个标记结合使用这个标记为std::once_flag其实once_flag是一个结构call_once()就是通过标记来决定函数是否执行调用成功后就把标记设置为一种已调用状态。 多个线程同时执行时使用call_once()一个线程会等待另一个线程先执行。
# includeiostream
# includethread
#includemutex
using namespace std;
once_flag g_flag;//标记来决定函数是否执行class MyClass {//单例类
private:MyClass() {}//私有化构造函数static MyClass* m_instance;//静态成员变量
public://用于call_once函数的第二个参数保证其只被调用一次static void CreateInstance() {m_instance new MyClass;static CGarhuishou cl;}//两个线程同时执行到这里其中一个线程要等另外一个线程执行完毕static MyClass* getInstance() {call_once(g_flag,CreateInstance);return m_instance;}class CGarhuishou {//类中套类用来释放对象public:~CGarhuishou() {if (MyClass::m_instance) {delete MyClass::m_instance;MyClass::m_instance NULL;}}};void func() {cout 测试 endl;}
};
MyClass* MyClass::m_instance NULL;//类内定义类外初始化//线程入口函数
void mythread() {cout myPrint线程开始执行了 endl;MyClass* p_a MyClass::getInstance();cout myPrint线程结束执行了 endl;
}
int main() {thread myobj1(mythread);thread myobj2(mythread);myobj1.join();myobj2.join();
}