概述
今天又复习了一下静态单例,但是以前只是知道实现静态单例的原理以及注意事项,写的代码也没有运行过,因为静态单例涉及到了多线程的知识,
并且我以前 只在Linux上用C语言的多线程,对windows下的C++多线程不了解。
带有多线程保护的静态单例原理我不细讲,网上一大堆,能运行的代码 我没找到(或者 我感觉那代码很乱,不符合自己口味)
今天下决心写一个能够运行的 带有多线程保护的(带互斥量)的静态单例,最主要是的 符合我的口味!
代码如下:
#include <iostream>
#include <thread> // std::thread
#include <mutex> // std::mutex
using namespace std;
/*用互斥量构建一个枷锁类*/
class Lock{
private:
mutex mtx;//互斥量
public:
void lock(){ mtx.lock(); }//加锁
void unlock(){ mtx.unlock(); }//解锁
};
/*静态单例*/
class singleton{
private:
int _value;//测试用值,静态单例在哪个线程中被第一次获取,_value的值就是哪个线程的id
singleton(int value);//构造函数
singleton(const singleton &);//复制构造函数
singleton& operator=(const singleton &);//赋值构造函数
public:
static Lock* Locker;//声明一个枷锁指针
static singleton* Instance;//声明一个对象
static singleton* getInstance(int thread_id);//声明获取单例的函数
int getValue();//获取测试值
~singleton();//析构函数
};
singleton::singleton(int value) :_value(value){}//构造函数
singleton::singleton(const singleton &){}//复制构造函数
singleton& singleton::operator=(const singleton &){ return *this; }//赋值构造函数
singleton::~singleton(){}//析构函数
Lock* singleton::Locker = new Lock();//初始化静态单例中的枷锁
singleton* singleton::Instance = NULL;//初始化静态单例
singleton* singleton::getInstance(int thread_id){//定义获取单例的函数
if (Instance == NULL){//由于加锁比较费事,所以先判断一次
Locker->lock();
if (Instance == NULL){
Instance = new singleton(thread_id);//初始化静态单例,参数为 线程的id
}
Locker->unlock();
}
return Instance;
}
int singleton::getValue(){//获取测试值
return _value;
}
mutex myMtx;//为了防止多个线程争夺 标准输出资源而设置的互斥量
void print_thread_id(int thread_id){//线程函数
singleton* Instance = singleton::getInstance(thread_id);//获取静态单例
myMtx.lock();
cout << "thread_id: " << thread_id << endl;
cout << "Instance is Created in thread: " << Instance->getValue() << endl;
myMtx.unlock();
}
int main(){
thread threads[2];//两个线程
int i;
for (i = 0; i < 2; ++i)
threads[i] = thread(print_thread_id, i);//启动线程
for (auto& th : threads) th.join();//等线程结束
return 0;
}
运行结果如下:说明 静态单利是在线程0中被创建的,也证明线程1中的对象与线程0中的对象是同一个!
注意:互斥量mutex是在c++11中才有的,这个代码是我在 Visual Studio 2013 上编写的!!!
有什么问题欢迎大家留言讨论
--------------------------------------------------
解释一下 “单例模式唯一实例为什么必须为静态”:
你只要弄明白单例模式是如何实现的,就能从本质上理解这个问题;
单例模式实现过程如下:
首先,将该类的构造函数私有化(目的是禁止其他程序创建该类的对象);
其次,在本类中自定义一个对象(既然禁止其他程序创建该类的对象,就要自己创建一个供程序使用,否则类就没法用,更不是单例);
最后,提供一个可访问类自定义对象的类成员方法(对外提供该对象的访问方式)。
直白的讲就是,你不能用该类在其他地方创建对象,而是通过该类自身提供的方法访问类中的那个自定义对象。
那么问题的关键来了,程序调用类中方法只有两种方式,
①创建类的一个对象,用该对象去调用类中方法;
②使用类名直接调用类中方法,格式“类名::方法名()”;
上面说了,构造函数私有化后第一种情况就不能用,只能使用第二种方法。
而使用类名直接调用类中的方法,类中方法必须是静态static的,而静态方法不能访问非静态成员变量,因此类自定义的实例变量也必须是静态的。
这就是单例模式唯一实例必须设置为静态的原因。~~~
最后
以上就是昏睡小白菜为你收集整理的完整的C++ 静态单例代码(带互斥量Mutex)的全部内容,希望文章能够帮你解决完整的C++ 静态单例代码(带互斥量Mutex)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复