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

来源:互联网 发布:淘宝店铺收藏有用吗 编辑:程序博客网 时间:2024/06/08 09:00


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

并且我以前 只在Linux上用C语言的多线程,对windows下的C++多线程不了解。

带有多线程保护的静态单例原理我不细讲,网上一大堆,能运行的代码 我没找到(或者 我感觉那代码很乱,不符合自己口味)

今天下决心写一个能够运行的 带有多线程保护的(带互斥量)的静态单例,最主要是的 符合我的口味

代码如下:


#include <iostream>#include <thread>         // std::thread #include <mutex>          // std::mutexusing namespace std;/*用互斥量构建一个枷锁类*/class Lock{private:mutex mtx;//互斥量public:void lock(){ mtx.lock(); }//加锁void unlock(){ mtx.unlock(); }//解锁};/*静态单例*/class singleton{private:int _value;//测试用值,静态单例在哪个线程中被第一次获取,_value的值就是哪个线程的idsingleton(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的,而静态方法不能访问非静态成员变量,因此类自定义的实例变量也必须是静态的
这就是单例模式唯一实例必须设置为静态的原因。~~~




原创粉丝点击