您的位置:首页 > 其它

临界区读取操作类 CRWCriticalSection

2015-01-26 00:00 393 查看
class CRWCriticalSection
{
public:
explicit CRWCriticalSection();
~CRWCriticalSection();

public:
BOOL LockReader(unsigned int nTimeOut = INFINITE);
void UnlockReader();
BOOL LockWriter(unsigned int nTimeOut = INFINITE);
void UnlockWriter();
private:
/*****/
HANDLE m_hNobodyIsReading;
HANDLE m_hWritingMutex;
CRITICAL_SECTION m_csReading;
unsigned int m_nReaders;

CRWCriticalSection(const CRWCriticalSection& cs);
CRWCriticalSection& operator=(const CRWCriticalSection& cs);
};

CRWCriticalSection::CRWCriticalSection()
{
// Create the flag that indicates if somebody is reading the object
//     initially, nobody is...
m_hNobodyIsReading = CreateEvent(NULL, TRUE, TRUE, NULL);

// Create a mutex indicating who is writing (only one)
m_hWritingMutex = CreateMutex(NULL, FALSE, NULL);

assert(m_hNobodyIsReading && m_hWritingMutex);

// Create the critical section for maintaining the number of readers
//   it should not delay much (so no need to analyse for deadlocks)
InitializeCriticalSection(&m_csReading);

m_nReaders = 0;
}

CRWCriticalSection::~CRWCriticalSection()
{
CloseHandle(m_hNobodyIsReading);
CloseHandle(m_hWritingMutex);
DeleteCriticalSection(&m_csReading);

assert(m_nReaders == 0);
}

BOOL CRWCriticalSection::LockReader(unsigned int nTimeout)
{
// We make sure that nobody is writing
if (WaitForSingleObject(m_hWritingMutex, nTimeout) != WAIT_OBJECT_0)
return FALSE;

// We need a critical section to update the number of readers
EnterCriticalSection(&m_csReading);
{
m_nReaders++;
if (m_nReaders == 1)
{
// We must indicate that there are some readers
ResetEvent(m_hNobodyIsReading);
}
}
LeaveCriticalSection(&m_csReading);

// I release the mutex for writing that I do not need
ReleaseMutex(m_hWritingMutex);

return TRUE;
}

void CRWCriticalSection::UnlockReader()
{
// We need a critical section to update the number of readers
EnterCriticalSection(&m_csReading);
{
m_nReaders--;
if (m_nReaders == 0)
{
// We indicate that there are no more readers
SetEvent(m_hNobodyIsReading);
}
}
LeaveCriticalSection(&m_csReading);
}

BOOL CRWCriticalSection::LockWriter(unsigned int nTimeout)
{
// Only one writer at a time
if (WaitForSingleObject(m_hWritingMutex,nTimeout) != WAIT_OBJECT_0)
return FALSE;

// Wait for all readers to leave
if (WaitForSingleObject(m_hNobodyIsReading,nTimeout) != WAIT_OBJECT_0)
{
// We have waited too long, so we have to set the "Writing" mutex
ReleaseMutex(m_hWritingMutex);
return FALSE;
}

return TRUE;
}

void CRWCriticalSection::UnlockWriter()
{
// Let other readers and writers in
ReleaseMutex(m_hWritingMutex);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: