比Windows临界区更快的线程同步锁
该代码仅经过在WIN32平台上的简单测试,不保证其安全性稳定性,对本代码造成的任何后果本人不负责任。 –FreeKnightDuzhi
#include <process.h>
using namespace std;
class FKFastLocker
{
private:
DWORD m_dwRecursiveCount;
#pragma pack( push, 8 );
volatile long m_lLock;
#pragma pack( pop );
public:
FKFastMutex() : m_lLock( 0 ), m_dwRecursiveCount(0){}
~FKFastMutex(){}
void Lock()
{
DWORD dwThreadID = GetCurrentThreadID();
DWORD dwOwner = 0;
if( dwThreadID == static_cast<DWORD>m_lLock )
{ ++m_dwRecursiveCount; return; }
while( true )
{ dwOwner = InterlockedCompareExchange( &m_lLock, dwThreadID, 0 );
if( 0 == dwOwner ){ break; }
Sleep(0); // 释放剩余CPU时间片
}
++m_dwRecursiveCount;
}
bool TryToLock()
{
DWORD dwThreadID = GetCurrentThreadID();
if( dwThreadID == static_cast<DWORD>m_lLock )
{ ++m_dwRecursiveCount; return true; }
DWORD dwOwner = InterlockedCompareExchange( &m_lLock, dwThreadID, 0 );
if( dwOwner == 0 )
{ ++m_dwRecursiveCount; return true; }
return false;
}
void UnLock()
{ if( ( --m_dwRecursiveCount ) == 0 }
{ InterlockedExchange(&m_lLock, 0 ) ;
}
}
因为是在公司内网里面做的,传出来非常不便。该死的百度又没有代码格式支持,所以就仅把代码放出,多线程测试过的,1000W次循环锁,用临界区需要22000毫秒,而该锁仅需1300毫秒。当然,在极少量锁的操作中,两者效率基本相等。
使用方式:
FKFastLocker cLocker;
cLocker.Lock();
// do your function
cLocker.UnLock();
注:该代码有优化余地。部分函数接口可避免平台相关。可传入时间参数进行定时Lock等操作,因为时间关系,简化出来放给大家,有兴趣的自己测试下把。