16,472
社区成员
发帖
与我相关
我的任务
分享
// 读写锁
class RWMutex
{
public:
inline RWMutex()
{
m_nWaitingReaders = m_nWaitingWriters = m_nActive = 0;
m_readSemaphore.Create(MAXLONG);
m_writeSemaphore.Create(MAXLONG);
}
inline virtual ~RWMutex()
{
#ifdef _DEBUG
// A SWMRG shouldn't be destroyed if any threads are using the resource
if (m_nActive != 0)
{
DebugBreak();
}
#endif
m_nWaitingReaders = m_nWaitingWriters = m_nActive = 0;
m_readSemaphore.Close();
m_writeSemaphore.Close();
}
inline void ReadLock(void)
{
m_mutex.Lock();
// Are there writers waiting or is a writer writing?
BOOL fResourceWritePending = (m_nWaitingWriters || (m_nActive < 0));
if(fResourceWritePending)
{
// This reader must wait, increment the count of waiting readers
m_nWaitingReaders++;
}
else
{
// This reader can read, increment the count of active readers
m_nActive++;
}
m_mutex.Unlock();
if (fResourceWritePending)
{
// This thread must wait
m_readSemaphore.Wait(INFINITE);
}
}
inline void WriteLock(void)
{
// Ensure exclusive access to the member variables
m_mutex.Lock();
// Are there any threads accessing the resource?
BOOL fResourceOwned = (m_nActive != 0);
if (fResourceOwned)
{
// This writer must wait, increment the count of waiting writers
m_nWaitingWriters++;
}
else
{
// This writer can write, decrement the count of active writers
m_nActive = -1;
}
m_mutex.Unlock();
if (fResourceOwned)
{
// This thread must wait
m_writeSemaphore.Wait(INFINITE);
}
}
inline void Unlock()
{
// Ensure exclusive access to the member variables
m_mutex.Lock();
if (m_nActive > 0)
{
// Readers have control so a reader must be done
m_nActive--;
}
else
{
// Writers have control so a writer must be done
m_nActive++;
}
// Assume no threads are waiting
Semaphore *pSemaphore = NULL;
// Assume only 1 waiter wakes; always true for writers
LONG lCount = 1;
if (m_nActive == 0)
{
// No thread has access, who should wake up?
// NOTE: It is possible that readers could never get access
// if there are always writers wanting to write
if (m_nWaitingWriters > 0)
{
// Writers are waiting and they take priority over readers
// A writer will get access
m_nActive = -1;
// Writers wait on this semaphore
pSemaphore = &m_writeSemaphore;
// One less writer will be waiting
m_nWaitingWriters--;
// NOTE: The semaphore will release only 1 writer thread
}
else if (m_nWaitingReaders > 0)
{
// Readers are waiting and no writers are waiting
// All readers will get access
m_nActive = m_nWaitingReaders;
// No readers will be waiting
m_nWaitingReaders = 0;
// Readers wait on this semaphore
pSemaphore = &m_readSemaphore;
// Semaphore releases all readers
lCount = m_nActive;
}
else
{
// There are no threads waiting at all; no semaphore gets released
}
}
// Allow other threads to attempt reading/writing
m_mutex.Unlock();
if (pSemaphore != NULL)
{
// Some threads are to be released
pSemaphore->Release(lCount);
}
}
private:
CriticalSection m_mutex;
Semaphore m_readSemaphore, m_writeSemaphore;
int m_nWaitingReaders, m_nWaitingWriters, m_nActive;
};
windows核心编程中的例子