c++线程之创建单例类、单例设计模式


/*
1、为什么不能在单例类的析构函数中进行delete
2、析构函数是在对象释放的时候才会执行的,就是说要手动delete才会窒息你个析构函数
3、当我们手动执行delete后,这时m_instance已经不存在了
4、如果在析构函数中执行delete m_instance,相当于delete了两次
*/


class MyCAS
{
private:
	MyCAS() {}   //私有化构造函数
 
private:
	static MyCAS* m_instance;  //静态成员变量

public:
	static MyCAS *GetInstance()
	{
		if (m_instance == NULL)
		{
			m_instance = new  MyCAS();
			static CGarhuishou cl; //程序退出的时候,会自动调用c1析构函数
		}
		return m_instance;
	}

	void func()
	{
		cout << "test" << endl;
	}

	class CGarhuishou //类中套类,用来释放对象
	{
	public:
		~CGarhuishou()
		{
			if (MyCAS::m_instance)
			{
				delete MyCAS::m_instance;
				MyCAS::m_instance = NULL;
			}
		}
	};

};

//静态变量初始化
MyCAS* MyCAS:: m_instance = NULL;


int main()
{
	MyCAS* p_a = MyCAS::GetInstance();
	//MyCAS* p_a = MyCAS::GetInstance(); //第二次调用 直接返回m_instance

	return 0;
}

上面代码是在主线程中创建的单例,没有任何问题;但是如果在多个子线程中创建单例,就有可能出现new 多个 m_instance了

void mythread()
{
	cout << "我的线程开始执行了" << endl;
	MyCAS* p_a = MyCAS::GetInstance();
	cout << "我的线程执行完毕了" << endl;
}

int main()
{

	//两个线程创建单例,就科能出现问题,可能都new 了 m_instance
	thread myobj1(mythread);
	thread myobj2(mythread);

	myobj1.join();
	myobj2.join();


	return 0;
}

在创建线程的时候,加互斥量能否解决这个问题呢? 确实可以解决
但是这样效率会很低,因为每次都要进入互斥量等待

    mutex my_mutex;
	static MyCAS *GetInstance()
	{
		unique_lock<mutex> unilock(my_mutex);
		//my_mutex.lock();
		if (m_instance == NULL)
		{
			m_instance = new  MyCAS();
			static CGarhuishou cl; //程序退出的时候,会自动调用c1析构函数
		}
		//my_mutex.unlock();
		return m_instance;
	}

再加一次 if (m_instance == NULL) 可以起到 双重检查的左右,后续创建的时候,根据m_instance 可以是否进入锁等待状态
在这里插入图片描述

call_once

c++引入的函数,该函数的第二个参数是一个函数名a()
call_once功能是能够保证函数a()只被调用一次
call_once具备互斥量这种能力,而且效率上,比互斥量消耗的更少

once_flag flag;
public:
	static void CreateInstance() //只被调用一次
	{
		m_instance = new MyCAS();
		static CGarhuishou cl;
	}


	static MyCAS *GetInstance()
	{
		call_once(flag, CreateInstance);
		return m_instance;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值