记录一个在VS2019将项目改为qt项目过程中遇到的问题(2)
`项目主要是一个多线程,功能包括从reids读取数据,进行处理,写入文件的项目:
由于之前的项目是用cmd命令行为输出,而cmd窗口模式一般显得低端还有个致命的问题是窗口模式鼠标的点击会造成线程的暂停等原因,于是就受到了这个任务
qt多线程的问题
本身项目是个多线程的项目,然后还有不少资源需要加锁竞争,并且项目本身不是自己写的,想要重新写一遍耗时更大;然而在运行的时候,第一次只是单纯的让主线程运行项目中一个类中的run函数(run函数主要),类中有信号发射器,能发射出字打印在屏幕中,当然结果很明显屏幕在启动后一动不动,此时意识到问题,然后开始寻找度娘,一顿操作下了解了qt多线程的实现,这个在后续文章会讲本项目用的解决方法,这期主要讲为了配合多线程我将类改成单例模式。
`
一、单例模式是什么?
单例模式是主要的模式,在应用中由于很多时候我们同一个类需要在整个项目保证他都是只有一个实例,类只给出一个全局访问点,项目中都仅能通过这个点访问;比如我的项目中,每个线程之间需要同一些资源,而由于我目前的实力,在qt多线程的实现上需要分多次去启动各个线程,这就造成了我必须保证每次都是通过一个实例,这时候单例模式的优势就出来了。
二、实现相关
1.静态变量和实例变量
这个比较基础,但是后续在这上面我也踩了一个坑,所以也记录一下。
语法上主要是静态变量在声明时多一个static关键字。运行时静态变量是跟类绑定一起的, 类在加载的时候静态变量就被分配了空间,就可以使用了;而实例变量顾名思义就是在类实例化后才被分配空间,才能使用,这就造成了有多少实例对象就会有多少实例变量,而静态变量一直都就只有一个。由于这个特性,于是类中就有如果将类的初始化函数私有,创建一个静态类对象,抛出一个获得静态对象接口,那么就能保证在整个项目运行期间用的都是同一个对象。
2.懒汉版和饿汉版
饿汉版代码如下:
class Singleton
{
private:
static Singleton instance;
private:
Singleton();
~Singleton();
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
public:
static Singleton& getInstance() {
return instance;
}
}
懒汉版代码如下:
class Singleton
{
private:
static Singleton* instance;
private:
Singleton() {};
~Singleton() {};
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
public:
static Singleton* getInstance()
{
if(instance == NULL)
instance = new Singleton();
return instance;
}
};
// init static member
Singleton* Singleton::instance = NULL;
我在项目中用的懒汉版,懒汉版一般文章都会着重讲的,代码是借鉴别人文章的,单例模式代码链接,自己的代码涉及到一些公司的就不贴了,主要还是一些记录,这个代码中的两个问题是有内存泄露危险和多线程初始化时会有资源抢夺问题,需要加把锁,于是有了下面进阶版代码
class Singleton
{
public:
static Singleton* getInstance() {
if (instance == nullptr) {
std::unique_lock<std::mutex> lock(m_Mutex);
instance = new Singleton();
}
return instance;
}
static void deleteInstance() {
std::unique_lock<std::mutex> lock(m_Mutex);
if (instance) {
delete instance;
instance = nullptr;
}
}
private:
static SLXMgr* slx_mgr_instance;
static std::mutex m_Mutex;
}
问题就在这里,我当时对着这段代码改了改写到了自己的程序,于是问题就来了,静态变量需要初始化,这里卡了我不少时间,倒不是因为不知道问题出现在需要初始化,而是mutex这个类我不知道要怎么初始化(果然还是太菜了),最后在源文件里添加
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::m_Mutex;