并发与多线程笔记7

1 设计模式

设计模式:代码的一些写法(跟常规写法不一样),程序灵活,维护起来可能方便,但别人接管或者阅读就会很难受。
用设计模式理念写出来的代码比较晦涩;应付大型项目时,把项目的开发经验、模块划分经验,总结整理而成。
建议:设计模式有着独特的优势,但要活学活用,不要深陷其中,生搬硬套。

2 单例设计模式

单例设计模式使用频率较高
单例:整个项目中,有某个或者某些特殊的类,属于该类的对象,只能创建一个。

#include <vector>
#include <thread>
#include <mutex>

using namespace std;

class Myclass //单例类
{
private:
	Myclass(){} //私有化了构造函数,只能他自己构造自己
private:
	static MyCAS *m_instance; // 静态成员变量
public:
	static MyCAS *GetIstance()
	{
		// 双重查锁,解决多个线程争夺锁问题。
		//if(m_instance == NULL)
		//{
			std::lock_guard<std::mutex> mymutex(Gmutex);//因为不能两个线程同时构造
			if(m_instance == NULL)
			{
				m_instance = new Myclass();
				//static helpRelease c1; //类内的静态数据成员,它始终驻留在全局数据区,直到程序运行结束。
			}
		//}
		
	}
	// 类中套类,解决析构问题
	//class helpRelease
	//{
	//public:
	//	helpRelease(){}
	//	~helpRelease()
	//	{
	//		if(MyCAS::m_instance)
	//		{
	//			delete Myclass::m_instance;
	//			Myclass::minstance = NULL;
	//		}
	//	}
	//};
};
// 线程入口函数
void mythread()
{
	cout << "线程开始:" << endl;

	MyCAS *p_a = MyCAS::GetIstance();
	cout << "线程结束:" << endl;

	return;
}
// 类静态变量初始化为空
MyCAS *MyCAS::m_instance = NULL;
int main()
{
	//Myclass *p_w = Myclass::GetInstance();//得到一个单例对象
	//MyCAS *p_b = MyCAS::GetIstance();// 还是原对象(可以查看其地址验证)
	std::thread mytobj1(mythread);
	std::thread mytobj2(mythread);

	mytobj1.join();
	mytobj2.join();

	return0;
}

如果没有注释代码,以上程序是存在风险的:

①new 生成的对象没有手动析构。—类中套类解决析构问题。
②每创建单例对象时多个线程都要争夺锁。----双重查锁,解决多线程重复拿锁的问题。

3 std::call_once() C++11引入的函数,该函数的第二个参数是一个函数名a()

功能:能够保证a()只调用一次。具备互斥量的能力,而且效率比互斥量更高。
需要和一个标记结合使用,这个标记 std::once_flag;其实once_flag是一个结构
通过此标记来决定函数a()是否执行,调用后就将此标记设置为已调用状态。
示例:

#include <iostream>
#include <vector>
#include <thread>
#include <mutex>


using namespace std;

std::mutex Gmutex;
std::once_flag g_flag;//这是个系统定义的标记

class MyCAS //单例类
{
	static void CreatInstance()//只调用一次的函数
	{
		std::chrono::microseconds dura(10000);
		std::this_thread::sleep_for(dura);

		m_instance = new MyCAS();// 想办法在程序结束后释放,怎么弄呢?
		static Releaseclass c1; // 类内的静态数据成员,它始终驻留在全局数据区,直到程序运行结束。
	}
private:
	MyCAS() {};//私有化了构造函数

private:
	static MyCAS *m_instance; // 静态成员变量

public:
	static MyCAS *GetIstance()
	{
		std::call_once(g_flag, CreatInstance);//几个线程一起来到这,只要有一个执行了,这个函数标记就说明不再执行了

		return m_instance;
	}

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

};


// 线程入口函数
void mythread()
{
	cout << "线程开始:" << endl;

	MyCAS *p_a = MyCAS::GetIstance();
	cout << "线程结束:" << endl;

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

int main()
{
	std::thread mytobj1(mythread);
	std::thread mytobj2(mythread);

	mytobj1.join();
	mytobj2.join();


	return 0;
}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宛如新生

转发即鼓励,打赏价更高!哈哈。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值