windows读写锁实现



#define RWLOCK_IDLE 0    
#define RWLOCK_R 0x01    
#define RWLOCK_W 0x02    
  
class RWLock  
{  
private:  
    int _st;   
    int _rlockCount;   
    int _rwaitingCount;   
    int _wwaitingCount;   
    HANDLE _ev;   
    //HANDLE _stLock;     
    CRITICAL_SECTION _stLock;   
public:  
    RWLock(void);  
    ~RWLock(void);  
    void rlock();  
    void wlock();  
    void unlock();  
};  
  
RWLock::RWLock(void)  
    : _rlockCount(0),  
    _st(RWLOCK_IDLE),  
    _rwaitingCount(0),  
    _wwaitingCount(0)  
{    
    InitializeCriticalSection(&_stLock);       
    _ev = CreateEvent(NULL, TRUE, FALSE, NULL);  //创建一个无名的不能被继承的无信号状态的事件对象,必须用ResetEvent函数来手工将事件的状态复原到无信号状态
    assert(_ev != INVALID_HANDLE_VALUE);  
}  
  
  
RWLock::~RWLock(void)  
{  
    //CloseHandle(_stLock);   
    DeleteCriticalSection(&_stLock);  
    CloseHandle(_ev);  
}  
  
void RWLock::rlock()  
{  
    bool isWaitReturn = false;  
    while(1)  
    {  
        //WaitForSingleObject(_stLock, INFINITE);   
        EnterCriticalSection(&_stLock);  
        if(isWaitReturn)  
        {               
            --_rwaitingCount;  
        }  
  
        if(_st == RWLOCK_IDLE)  
        {               
            _st = RWLOCK_R;  //初始化状态,直接加读锁
            _rlockCount++;  
            //ReleaseMutex(_stLock);   
            LeaveCriticalSection(&_stLock);  
            break;  
        }  
        else if( _st == RWLOCK_R)  
        {  
            if(_wwaitingCount > 0) //这样写是模拟锁队列? 
            {                   
                ++_rwaitingCount;  
                ResetEvent(_ev);  
                //SignalObjectAndWait(_stLock, _ev, INFINITE, FALSE);   
                LeaveCriticalSection(&_stLock);  
                WaitForSingleObject(_ev, INFINITE);                
                isWaitReturn = true;  
            }  
            else  
            {                      
                ++_rlockCount;  
                //ReleaseMutex(_stLock);   
                LeaveCriticalSection(&_stLock);  
                break;  
            }  
        }  
        else if(_st == RWLOCK_W)  
        {               
            ++_rwaitingCount;  //写锁状态,读等待数量自加
            ResetEvent(_ev);  
            //SignalObjectAndWait(_stLock, _ev, INFINITE, FALSE);   
            LeaveCriticalSection(&_stLock);  
            WaitForSingleObject(_ev, INFINITE);  
            isWaitReturn = true;  
        }  
        else  
        {  
            assert(0);  
            break;  
        }  
    }  
}  
  
void RWLock::wlock()  
{  
    bool isWaitReturn = false;    
    while(1)  //循环判断锁释放情况
    {
        //WaitForSingleObject(_stLock, INFINITE);   
        EnterCriticalSection(&_stLock);     //保护数量和信号
        if(isWaitReturn) 
{
--_wwaitingCount;    //后续有等到锁闲置,写锁先自减
}
        if(_st == RWLOCK_IDLE)  
        {  
            _st = RWLOCK_W;  //抢到写锁,设置锁状态
            //ReleaseMutex(_stLock);   
            LeaveCriticalSection(&_stLock);  
            break;  //结束等待
        }  
        else  
        {  
            ++_wwaitingCount;  //没抢到锁,写锁数量自加
            ResetEvent(_ev);  
            //SignalObjectAndWait(_stLock, _ev, INFINITE, FALSE);   
            LeaveCriticalSection(&_stLock); 
            WaitForSingleObject(_ev, INFINITE);  
            isWaitReturn = true;  
        }  
    }  
}  
  
void RWLock::unlock()  
{  
    //WaitForSingleObject(_stLock, INFINITE);   
    EnterCriticalSection(&_stLock);  
    if(_rlockCount > 0)  
    {      
//如果读锁数量还有,解锁将直接自减读数
        --_rlockCount;  
        if( 0 == _rlockCount)  
        {  
//如果解锁后,读数自减到0,则初始化锁状态为闲置
            _st = RWLOCK_IDLE;  
            if( _wwaitingCount > 0 || _rwaitingCount > 0 )  
            {                
                SetEvent(_ev);  //锁初始化为闲置时,如果有读写锁等待,则发信号通知  
            }  
        }  
    }  
    else  
    {  
        _st = RWLOCK_IDLE;  //如果没有读锁,解锁将直接初始化锁状态为闲置
        if( _wwaitingCount > 0 || _rwaitingCount > 0 )  
        {               
            SetEvent(_ev);//锁初始化为闲置时,如果有读写锁等待,则发信号通知  
        }  
    }  
    //ReleaseMutex(_stLock);   
    LeaveCriticalSection(&_stLock);  
}  





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值