完整的C++ 静态单例代码(带互斥量Mutex)


今天又复习了一下静态单例,但是以前只是知道实现静态单例的原理以及注意事项,写的代码也没有运行过,因为静态单例涉及到了多线程的知识,

并且我以前 只在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的,而静态方法不能访问非静态成员变量,因此类自定义的实例变量也必须是静态的
这就是单例模式唯一实例必须设置为静态的原因。~~~




  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值