#define RWLOCK_IDLE 0
#define RWLOCK_R 0x01
#define RWLOCK_W 0x02
class RWLock
{
private:
int _st;
int _rlockCount;
int _rwaitingCount;
int _wwaitingCount;
HANDLE _ev;
//HANDLE _stLock;
CRITICAL_SECTION _stLock;
public:
RWLock(void);
~RWLock(void);
void rlock();
void wlock();
void unlock();
};
RWLock::RWLock(void)
: _rlockCount(0),
_st(RWLOCK_IDLE),
_rwaitingCount(0),
_wwaitingCount(0)
{
InitializeCriticalSection(&_stLock);
_ev = CreateEvent(NULL, TRUE, FALSE, NULL); //创建一个无名的不能被继承的无信号状态的事件对象,必须用ResetEvent函数来手工将事件的状态复原到无信号状态
assert(_ev != INVALID_HANDLE_VALUE);
}
RWLock::~RWLock(void)
{
//CloseHandle(_stLock);
DeleteCriticalSection(&_stLock);
CloseHandle(_ev);
}
void RWLock::rlock()
{
bool isWaitReturn = false;
while(1)
{
//WaitForSingleObject(_stLock, INFINITE);
EnterCriticalSection(&_stLock);
if(isWaitReturn)
{
--_rwaitingCount;
}
if(_st == RWLOCK_IDLE)
{
_st = RWLOCK_R; //初始化状态,直接加读锁
_rlockCount++;
//ReleaseMutex(_stLock);
LeaveCriticalSection(&_stLock);
break;
}
else if( _st == RWLOCK_R)
{
if(_wwaitingCount > 0) //这样写是模拟锁队列?
{
++_rwaitingCount;
ResetEvent(_ev);
//SignalObjectAndWait(_stLock, _ev, INFINITE, FALSE);
LeaveCriticalSection(&_stLock);
WaitForSingleObject(_ev, INFINITE);
isWaitReturn = true;
}
else
{
++_rlockCount;
//ReleaseMutex(_stLock);
LeaveCriticalSection(&_stLock);
break;
}
}
else if(_st == RWLOCK_W)
{
++_rwaitingCount; //写锁状态,读等待数量自加
ResetEvent(_ev);
//SignalObjectAndWait(_stLock, _ev, INFINITE, FALSE);
LeaveCriticalSection(&_stLock);
WaitForSingleObject(_ev, INFINITE);
isWaitReturn = true;
}
else
{
assert(0);
break;
}
}
}
void RWLock::wlock()
{
bool isWaitReturn = false;
while(1) //循环判断锁释放情况
{
//WaitForSingleObject(_stLock, INFINITE);
EnterCriticalSection(&_stLock); //保护数量和信号
if(isWaitReturn)
{
--_wwaitingCount; //后续有等到锁闲置,写锁先自减
}
if(_st == RWLOCK_IDLE)
{
_st = RWLOCK_W; //抢到写锁,设置锁状态
//ReleaseMutex(_stLock);
LeaveCriticalSection(&_stLock);
break; //结束等待
}
else
{
++_wwaitingCount; //没抢到锁,写锁数量自加
ResetEvent(_ev);
//SignalObjectAndWait(_stLock, _ev, INFINITE, FALSE);
LeaveCriticalSection(&_stLock);
WaitForSingleObject(_ev, INFINITE);
isWaitReturn = true;
}
}
}
void RWLock::unlock()
{
//WaitForSingleObject(_stLock, INFINITE);
EnterCriticalSection(&_stLock);
if(_rlockCount > 0)
{
//如果读锁数量还有,解锁将直接自减读数
--_rlockCount;
if( 0 == _rlockCount)
{
//如果解锁后,读数自减到0,则初始化锁状态为闲置
_st = RWLOCK_IDLE;
if( _wwaitingCount > 0 || _rwaitingCount > 0 )
{
SetEvent(_ev); //锁初始化为闲置时,如果有读写锁等待,则发信号通知
}
}
}
else
{
_st = RWLOCK_IDLE; //如果没有读锁,解锁将直接初始化锁状态为闲置
if( _wwaitingCount > 0 || _rwaitingCount > 0 )
{
SetEvent(_ev);//锁初始化为闲置时,如果有读写锁等待,则发信号通知
}
}
//ReleaseMutex(_stLock);
LeaveCriticalSection(&_stLock);
}