目录
一、设计模式
- 程序灵活,维护起来可能方便,用设计模式理念写出来的代码很晦涩,但是别人接管、阅读代码都会很痛苦
- 老外应付特别大的项目时,把项目的开发经验、模块划分经验,总结整理成设计模式
- 中国零几年设计模式刚开始火时,总喜欢拿一个设计模式往上套,导致一个小小的项目总要加几个设计模式,本末倒置
- 设计模式有其独特的优点,要活学活用,不要深陷其中,生搬硬套
二、单例设计模式
整个项目中,有某个或者某些特殊的类,只能创建一个属于该类的对象。
单例类:只能生成一个对象。
三、单例设计模式共享数据分析、解决
面临问题:需要在自己创建的线程中来创建单例类的对象,这种线程可能不止一个。我们可能面临GetInstance()
这种成员函数需要互斥。
可以在加锁前判断m_instance
是否为空,否则每次调用Singelton::getInstance()
都要加锁,十分影响效率。
虽然这两个线程 是同一个入口函数,但是千万要记住,这是两个线程,所以这里会有两个流程同时开始执行mythread,实例如下:
#include<iostream>
#include<thread>
#include<string>
#include<vector>
#include<list>
#include<mutex>
using namespace std;
std::mutex resource_mutex;
class MyCAS
{
private:
MyCAS() {} //私有化了的构造函数
private:
static MyCAS *m_instance; //静态成员变量
public:
static MyCAS *GetInstance()
{
//提高效率
//a)如果if (m_instance != NULL) 条件成立,则肯定表示m_instance已经被new过了;
//b)如果if (m_instance == NULL),不代表m_instance一定没被new过;
if (m_instance == NULL) //双重锁定(双程检查)
{
std::unique_lock<std::mutex> mymutex(resource_mutex); //自动加锁,但效率非常低
if (m_instance == NULL)
{
m_instance == new MyCAS();
static CGarhuishou cl;
}
}
return m_instance;
}
class CGarhuishou //类中套类,用来释放对象
{
public:
~CGarhuishou() //类的析构函数中
{
if (MyCAS::m_instance)
{
delete MyCAS::m_instance;
MyCAS::m_instance = NULL;
}
}
};
void func()
{
cout << "测试" << endl;
}
};
//类静态变量初始化
MyCAS *MyCAS::m_instance = NULL;
//线程入口函数
void mythread()
{
cout <<"我的线程开始执行了" << endl;
MyCAS *p_a = MyCAS::GetInstance(); //这里可能就有问题了
cout << "我的线程执行完毕了" << endl;
}
int main()
{
std::thread myobj1(mythread);
std::thread myobj2(mythread);
myobj1.join();
myobj2.join();
return 0;
}
四、std::call_once():
C++11引入的函数,该函数的第二个参数是一个函数名a();
std::call_once()
功能是能够保证函数a()只被调用一次,具备互斥量这种能力,而且效率上比互斥量消耗的资源更小;
std::call_once()
需要与一个标记结合使用,这个标记std::once_flag
;其实once_flag
是一个结构;
std::call_once()
就是通过这个标记决定对应函数a()是否执行,调用call_once()
成功后,std::call_once()
就把这个标记设置为一种已调用状态,后续继续调用std::call_once()
,只要once_flag
被设置为了“已调用”状态,那么对应的函数a()就不会再被执行了;实例代码如下:
once_flag g_flag;
class Singelton
{
public:
static void CreateInstance()//call_once保证其只被调用一次
{
instance = new Singelton;
}
//两个线程同时执行到这里,其中一个线程要等另外一个线程执行完毕
static Singelton * getInstance() {
call_once(g_flag, CreateInstance);
return instance;
}
private:
Singelton() {}
static Singelton *instance;
};
Singelton * Singelton::instance = NULL;
整体代码:
#include<iostream>
#include<thread>
#include<string>
#include<vector>
#include<list>
#include<mutex>
using namespace std;
std::mutex resource_mutex;
std::once_flag g_flag;//这是个系统定义的标记
class MyCAS
{
static void CreateInstance()//只被调用一次
{
std::chrono::microseconds dura(20000);
std::this_thread::sleep_for(dura);
m_instance == new MyCAS();
static CGarhuishou cl;
}
private:
MyCAS() {} //私有化了的构造函数
private:
static MyCAS *m_instance; //静态成员变量
public:
static MyCAS *GetInstance()
{
//两个线程同时执行到这里,其中一个线程要等另外一个线程执行完毕CreateInstance(),这里可以把g_flag看作一把锁
std::call_once(g_flag, CreateInstance);
cout << "call_once()执行完毕" << endl;
return m_instance;
}
class CGarhuishou //类中套类,用来释放对象
{
public:
~CGarhuishou() //类的析构函数中
{
if (MyCAS::m_instance)
{
delete MyCAS::m_instance;
MyCAS::m_instance = NULL;
}
}
};
void func()
{
cout << "测试" << endl;
}
};
//类静态变量初始化
MyCAS *MyCAS::m_instance = NULL;
//线程入口函数
void mythread()
{
cout << "我的线程开始执行了" << endl;
MyCAS *p_a = MyCAS::GetInstance(); //这里可能就有问题了
cout << "我的线程执行完毕了" << endl;
}
int main()
{
std::thread myobj1(mythread);
std::thread myobj2(mythread);
myobj1.join();
myobj2.join();
return 0;
}