// 一个Windows下C++读写锁的代码,实现共享读,独占写
class ReadWriteLock
{
public:
int m_currentLevel;
int m_readCount;
HANDLE m_unlockEvent;
HANDLE m_accessMutex;
CRITICAL_SECTION m_csStateChange;
public:
ReadWriteLock()
{
m_currentLevel = LOCK_LEVEL_NONE;
m_readCount = 0;
m_unlockEvent = ::CreateEvent( NULL, TRUE, FALSE, NULL );
m_accessMutex = ::CreateMutex( NULL, FALSE, NULL );
::InitializeCriticalSection( &m_csStateChange );
}
~ReadWriteLock()
{
::DeleteCriticalSection( &m_csStateChange );
if ( m_accessMutex ) ::CloseHandle( m_accessMutex );
if ( m_unlockEvent ) ::CloseHandle( m_unlockEvent );
}
bool lock( int level, int timeout = INFINITE)
{
bool bresult = true;
DWORD waitResult = 0;
waitResult = ::WaitForSingleObject( m_accessMutex, timeout );
if ( waitResult != WAIT_OBJECT_0 ) return false;
if ( level == LOCK_LEVEL_READ && m_currentLevel != LOCK_LEVEL_WRITE )
{
::EnterCriticalSection( &m_csStateChange );
m_currentLevel = level;
m_readCount += 1;
::ResetEvent( m_unlockEvent );
::LeaveCriticalSection( &m_csStateChange );
}
else if ( level == LOCK_LEVEL_READ &&
m_currentLevel == LOCK_LEVEL_WRITE )
{
waitResult = ::WaitForSingleObject( m_unlockEvent, timeout );
if ( waitResult == WAIT_OBJECT_0 )
{
::EnterCriticalSection( &m_csStateChange );
m_currentLevel = level;
m_readCount += 1;
::ResetEvent( m_unlockEvent );
::LeaveCriticalSection( &m_csStateChange );
}
else bresult = false;
}
else if ( level == LOCK_LEVEL_WRITE &&
m_currentLevel == LOCK_LEVEL_NONE )
{
::EnterCriticalSection( &m_csStateChange );
m_currentLevel = level;
::ResetEvent( m_unlockEvent );
::LeaveCriticalSection( &m_csStateChange );
}
else if ( level == LOCK_LEVEL_WRITE &&
m_currentLevel != LOCK_LEVEL_NONE )
{
waitResult = ::WaitForSingleObject( m_unlockEvent, timeout );
if ( waitResult == WAIT_OBJECT_0 )
{
::EnterCriticalSection( &m_csStateChange );
m_currentLevel = level;
::ResetEvent( m_unlockEvent );
::LeaveCriticalSection( &m_csStateChange );
}
else bresult = false;
}
::ReleaseMutex( m_accessMutex );
return bresult;
} // lock()
bool unlock()
{
::EnterCriticalSection( &m_csStateChange );
if ( m_currentLevel == LOCK_LEVEL_READ )
{
m_readCount --;
if ( m_readCount == 0 )
{
m_currentLevel = LOCK_LEVEL_NONE;
::SetEvent (m_unlockEvent);
}
}
else if ( m_currentLevel == LOCK_LEVEL_WRITE )
{
m_currentLevel = LOCK_LEVEL_NONE;
::SetEvent ( m_unlockEvent );
}
::LeaveCriticalSection( &m_csStateChange );
return true;
}
};
class ReadWriteLock
{
public:
int m_currentLevel;
int m_readCount;
HANDLE m_unlockEvent;
HANDLE m_accessMutex;
CRITICAL_SECTION m_csStateChange;
public:
ReadWriteLock()
{
m_currentLevel = LOCK_LEVEL_NONE;
m_readCount = 0;
m_unlockEvent = ::CreateEvent( NULL, TRUE, FALSE, NULL );
m_accessMutex = ::CreateMutex( NULL, FALSE, NULL );
::InitializeCriticalSection( &m_csStateChange );
}
~ReadWriteLock()
{
::DeleteCriticalSection( &m_csStateChange );
if ( m_accessMutex ) ::CloseHandle( m_accessMutex );
if ( m_unlockEvent ) ::CloseHandle( m_unlockEvent );
}
bool lock( int level, int timeout = INFINITE)
{
bool bresult = true;
DWORD waitResult = 0;
waitResult = ::WaitForSingleObject( m_accessMutex, timeout );
if ( waitResult != WAIT_OBJECT_0 ) return false;
if ( level == LOCK_LEVEL_READ && m_currentLevel != LOCK_LEVEL_WRITE )
{
::EnterCriticalSection( &m_csStateChange );
m_currentLevel = level;
m_readCount += 1;
::ResetEvent( m_unlockEvent );
::LeaveCriticalSection( &m_csStateChange );
}
else if ( level == LOCK_LEVEL_READ &&
m_currentLevel == LOCK_LEVEL_WRITE )
{
waitResult = ::WaitForSingleObject( m_unlockEvent, timeout );
if ( waitResult == WAIT_OBJECT_0 )
{
::EnterCriticalSection( &m_csStateChange );
m_currentLevel = level;
m_readCount += 1;
::ResetEvent( m_unlockEvent );
::LeaveCriticalSection( &m_csStateChange );
}
else bresult = false;
}
else if ( level == LOCK_LEVEL_WRITE &&
m_currentLevel == LOCK_LEVEL_NONE )
{
::EnterCriticalSection( &m_csStateChange );
m_currentLevel = level;
::ResetEvent( m_unlockEvent );
::LeaveCriticalSection( &m_csStateChange );
}
else if ( level == LOCK_LEVEL_WRITE &&
m_currentLevel != LOCK_LEVEL_NONE )
{
waitResult = ::WaitForSingleObject( m_unlockEvent, timeout );
if ( waitResult == WAIT_OBJECT_0 )
{
::EnterCriticalSection( &m_csStateChange );
m_currentLevel = level;
::ResetEvent( m_unlockEvent );
::LeaveCriticalSection( &m_csStateChange );
}
else bresult = false;
}
::ReleaseMutex( m_accessMutex );
return bresult;
} // lock()
bool unlock()
{
::EnterCriticalSection( &m_csStateChange );
if ( m_currentLevel == LOCK_LEVEL_READ )
{
m_readCount --;
if ( m_readCount == 0 )
{
m_currentLevel = LOCK_LEVEL_NONE;
::SetEvent (m_unlockEvent);
}
}
else if ( m_currentLevel == LOCK_LEVEL_WRITE )
{
m_currentLevel = LOCK_LEVEL_NONE;
::SetEvent ( m_unlockEvent );
}
::LeaveCriticalSection( &m_csStateChange );
return true;
}
};

本文介绍了一个简单的Windows环境下用C++实现的读写锁。该读写锁允许多个线程同时进行读操作,但只允许一个线程进行写操作。通过使用互斥量、事件对象和临界区等同步机制来确保线程安全。

被折叠的 条评论
为什么被折叠?



