C++读写锁例子的代码

将写代码过程中经常用的代码片段做个收藏,下面资料是关于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

猜你喜欢

转载自blog.csdn.net/weixin_44201346/article/details/86701203