将写代码过程中经常用的代码片段做个收藏,下面资料是关于C++读写锁例子的代码,希望对大伙也有帮助。
#ifndef _READWRITELOCK_H_
#define _READWRITELOCK_H_
#include <limits.h>
#define RWLOCK_LEVEL_SHAERREAD -1L
#define RWLOCK_LEVEL_FREEE 0L
#define RWLOCK_LEVEL_WAITREAD 1L
#define RWLOCK_LEVEL_WAITREADEND 2L
#define RWLOCK_LEVEL_EXCLUSIVE 3L
#ifdef _MULTI_PROCESSOR_
#else
#define SpinWait(n) Sleep(n)
#endif
#define SpinOnCondition(Condition) while (Condition) {
SpinWait(1);
}
__declspec(align( 4 ))
struct _ReadWriteLock_t
{
volatile long lLockLevel;
volatile long lIncomingReader;
volatile long lCurrentReaders;
volatile long lWriterCount;
long lRecursiveLevel;
DWORD dwOwnerThreadId;
};
typedef _ReadWriteLock_t RWLOCK;
inline
void InitializeRWLock(LPRWLOCK lock){
lock->lLockLevel = RWLOCK_LEVEL_FREEE;
lock->lIncomingReader = 0L;
lock->lCurrentReaders = 0L;
lock->lWriterCount = 0L;
lock->dwOwnerThreadId = (DWORD)-1;
lock->lRecursiveLevel = -1L;
}
inline
void AcquireWrite(LPRWLOCK lock){
if((DWORD)-1 != lock->dwOwnerThreadId && GetCurrentThreadId() == lock->dwOwnerThreadId) {
lock->lRecursiveLevel++;
return;
}
long lTemp1,lTemp2;
DWORD dwTest = 0;
InterlockedCompareExchange(&lock->lLockLevel,RWLOCK_LEVEL_WAITREAD,RWLOCK_LEVEL_SHAERREAD);
InterlockedIncrement(&lock->lWriterCount);
do {
SpinOnCondition(RWLOCK_LEVEL_FREEE != lock->lLockLevel && RWLOCK_LEVEL_WAITREADEND != lock->lLockLevel);
lTemp1 = InterlockedCompareExchange(&lock->lLockLevel,RWLOCK_LEVEL_EXCLUSIVE,RWLOCK_LEVEL_FREEE);
lTemp2 = InterlockedCompareExchange(&lock->lLockLevel,RWLOCK_LEVEL_EXCLUSIVE,RWLOCK_LEVEL_WAITREADEND);
} while (RWLOCK_LEVEL_FREEE != lTemp1 && RWLOCK_LEVEL_WAITREADEND != lTemp2);
lock->dwOwnerThreadId = GetCurrentThreadId();
lock->lRecursiveLevel++;
}
inline
void AcquireRead(LPRWLOCK lock){
long lTemp = lock->lLockLevel;
long lTemp1 = InterlockedIncrement(&lock->lIncomingReader);
if (RWLOCK_LEVEL_SHAERREAD == lTemp) {
if (lTemp1 > 0L) {
InterlockedIncrement(&lock->lCurrentReaders);
InterlockedDecrement(&lock->lIncomingReader);
return;
}
} else {
InterlockedDecrement(&lock->lIncomingReader);
}
while (RWLOCK_LEVEL_SHAERREAD != lTemp && RWLOCK_LEVEL_FREEE != lTemp){
SpinOnCondition(RWLOCK_LEVEL_FREEE != lock->lLockLevel && RWLOCK_LEVEL_SHAERREAD != lock->lLockLevel);
lTemp = InterlockedCompareExchange(&lock->lLockLevel,RWLOCK_LEVEL_SHAERREAD,RWLOCK_LEVEL_FREEE);
}
InterlockedIncrement(&lock->lCurrentReaders);
}
inline
void ReleaseRead(LPRWLOCK lock){
long lReaderRemain = InterlockedDecrement(&lock->lCurrentReaders);
if (0L == lReaderRemain) {
long lLockComing = InterlockedCompareExchange(&lock->lIncomingReader,-LONG_MAX,0L);
if (0L == lLockComing) {
InterlockedCompareExchange(&lock->lLockLevel,RWLOCK_LEVEL_FREEE,RWLOCK_LEVEL_SHAERREAD);
InterlockedCompareExchange(&lock->lLockLevel,RWLOCK_LEVEL_WAITREADEND,RWLOCK_LEVEL_WAITREAD);
lock->lIncomingReader = 0;
}
}
}
inline
void ReleaseWrite(LPRWLOCK lock){
lock->lRecursiveLevel--;
if(-1L != lock->lRecursiveLevel) {
return;
}
lock->dwOwnerThreadId = (DWORD)-1;
long lTemp = InterlockedDecrement(&lock->lWriterCount);
if (0L == lTemp) {
InterlockedCompareExchange(&lock->lLockLevel,RWLOCK_LEVEL_FREEE,RWLOCK_LEVEL_EXCLUSIVE);
} else {
InterlockedCompareExchange(&lock->lLockLevel,RWLOCK_LEVEL_WAITREADEND,RWLOCK_LEVEL_EXCLUSIVE);
}
}
#endif