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被析构,解锁 }
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: STL之效率比较
- 下一篇: ThinkPHP 验证码 session被清空