C++多线程同步效率对比之临界区和原子锁

多线程编程经常遇到数据同步问题,通常的做法就是加锁,之前个人常用临界区(CTITICAL_SECTION),最近开发高效率程序,寻求更高效的同步方式,才有了对原子锁的研究。经测试,原子锁效率确实比临界区高,用数据衡量,原子锁的效率是临界区的5倍左右。

测试方法:

1、主线程加锁

2、工作线程等待

3、主线程解锁

4、工作线程结束等待

测试结果:测试3、4步骤之间的耗时,临界区耗时5~6微秒,原子锁耗时1~2微秒。


关于临界区和原子锁,请baidu看看相关文章,这里不多介绍了。注意原子锁不能嵌套使用,否则会被锁死,临界区没这个问题。


包装了两个类分别实现临界区(CLock)和原子锁(CLockAtom),同时包装了两个在作用域中方便使用的类(CLockRegion和CLockAtomRegion),具体使用见下面代码。

CLock类

#include <windows.h>

namespace UtilTool {

	class CLock
	{
	public:
		CLock(void)
		{
			InitializeCriticalSection(&cs);
		}
		
		~CLock(void)
		{
			DeleteCriticalSection(&cs);
		}

		inline void Lock()
		{
			EnterCriticalSection(&cs);
		}
		
		inline void UnLock()
		{
			LeaveCriticalSection(&cs);
		}
		
	private:
		CRITICAL_SECTION cs;
	};

	class CLockRegion
	{
	public:
		CLockRegion(CLock* lock) : m_lock(lock)
		{
			m_lock->Lock();
		}

		~CLockRegion()
		{
			m_lock->UnLock();
		}
	private:
		CLock* m_lock;
	};
}

CLockAtom类

#include <windows.h>

namespace UtilTool {

	struct _UTILTOOL_IMPORT_EXPORT_TYPE_ CAtom
	{
	public:
		CAtom()
		{
			m_l = 0;
		}

		volatile long* Get()
		{
			return &m_l;
		}
	private:
		volatile long m_l;
	};

	//原子锁
	//切忌嵌套使用
	class CLockAtom
	{
	public:
		CLockAtom(void)
		{
			m_ics = 0;
		}
		
		~CLockAtom(void){}

		inline void Lock()
		{
			while (InterlockedExchange(&m_ics, 1) == 1)
			{
				Sleep(0);
			}
		}
		
		inline void UnLock()
		{
			InterlockedExchange(&m_ics, 0);
		}

		static inline void Lock(CAtom* pAtom)
		{
			while (InterlockedExchange(pAtom->Get(), 1) == 1)
			{
				Sleep(0);
			}
		}

		static inline void UnLock(CAtom* pAtom)
		{
			InterlockedExchange(pAtom->Get(), 0);
		}
		
	private:
		volatile long m_ics;
	};

	class CLockAtomRegion
	{
	public:
		CLockAtomRegion(CLockAtom* lock)
		{
			m_atom = NULL;
			m_lock = lock;
			m_lock->Lock();
		}

		CLockAtomRegion(CAtom* atom)
		{
			m_atom = atom;
			m_lock = NULL;
			CLockAtom::Lock(m_atom);
		}

		~CLockAtomRegion()
		{
			if (m_lock)
			{
				m_lock->UnLock();
			}
			else if (m_atom)
			{
				CLockAtom::UnLock(m_atom);
			}
		}
	private:
		CLockAtom* m_lock;
		CAtom* m_atom;
	};
}

CLockRegion的用法,CLockAtomRegion类似

CLock lock;

void MyFunc()
{
	//进入函数,_lock被创建,调用CLockRegion构造函数,加锁
	CLockRegion _lock(&lock);

	//do something

	//函数退出,_lock被析构,解锁
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值