读写锁_用互斥和事件实现
来源:互联网 发布:linux gzip 压缩 编辑:程序博客网 时间:2024/06/12 01:31
#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; /* 通知事件 Event */
//HANDLE _stLock; /* 访问状态值互斥量 */ /* 如果需要等待超时,则用 Mutex */
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)
{
//_stLock = CreateMutex(NULL, FALSE, NULL);
//assert(_stLock != INVALID_HANDLE_VALUE);
InitializeCriticalSection(&_stLock);
/*
* 假设当前有多个读锁请求正在等待写锁释放,那么当写锁被释放时,所有这些读锁都应该有机会获得执行.
*/
_ev = CreateEvent(NULL, TRUE, FALSE, NULL);
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);
/*
* 虽然 LeaveCriticalSection() 和 WaitForSingleObject() 之间有一个时间窗口,
* 但是由于windows平台的事件信号是不会丢失的,所以没有问题.
*/
WaitForSingleObject(_ev, INFINITE);
/*
* 等待返回,继续尝试加锁.
*/
isWaitReturn = true;
}
else
{
/*
* 得到读锁,计数+1
*/
++_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)
{
_st = RWLOCK_IDLE;
/* 释放 */
if( _wwaitingCount > 0 || _rwaitingCount > 0 )
{
/*
* 此时有锁请求正在等待,激活所有等待的线程.(手动事件).
* 使这些请求重新竞争锁.
*/
SetEvent(_ev);
}
else
{
/* 空闲 */
}
}
else
{
/* 还有读锁 */
}
}
else
{
_st = RWLOCK_IDLE;
/* 写锁解锁 */
if( _wwaitingCount > 0 || _rwaitingCount > 0 )
{
/*
* 如果在占有互斥量_stLock的情况下,触发事件,那么可能会使一些锁请求不能得到竞争机会.
* 假设调用unlock时,另一个线程正好调用rlock或者wlock.如果不释放互斥量,只有之前已经等待的锁请求有机会获得锁控制权.
*/
SetEvent(_ev);
}
else
{
/* 空闲 */
}
}
//ReleaseMutex(_stLock);
LeaveCriticalSection(&_stLock);
}
#define RWLOCK_R 0x01 /* 读锁 */
#define RWLOCK_W 0x02 /* 写锁 */
class RWLock
{
private:
int _st; /* 锁状态值 */
int _rlockCount; /* 读锁计数 */
int _rwaitingCount; /* 读等待计数 */
int _wwaitingCount; /* 写等待计数 */
HANDLE _ev; /* 通知事件 Event */
//HANDLE _stLock; /* 访问状态值互斥量 */ /* 如果需要等待超时,则用 Mutex */
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)
{
//_stLock = CreateMutex(NULL, FALSE, NULL);
//assert(_stLock != INVALID_HANDLE_VALUE);
InitializeCriticalSection(&_stLock);
/*
* 假设当前有多个读锁请求正在等待写锁释放,那么当写锁被释放时,所有这些读锁都应该有机会获得执行.
*/
_ev = CreateEvent(NULL, TRUE, FALSE, NULL);
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);
/*
* 虽然 LeaveCriticalSection() 和 WaitForSingleObject() 之间有一个时间窗口,
* 但是由于windows平台的事件信号是不会丢失的,所以没有问题.
*/
WaitForSingleObject(_ev, INFINITE);
/*
* 等待返回,继续尝试加锁.
*/
isWaitReturn = true;
}
else
{
/*
* 得到读锁,计数+1
*/
++_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)
{
_st = RWLOCK_IDLE;
/* 释放 */
if( _wwaitingCount > 0 || _rwaitingCount > 0 )
{
/*
* 此时有锁请求正在等待,激活所有等待的线程.(手动事件).
* 使这些请求重新竞争锁.
*/
SetEvent(_ev);
}
else
{
/* 空闲 */
}
}
else
{
/* 还有读锁 */
}
}
else
{
_st = RWLOCK_IDLE;
/* 写锁解锁 */
if( _wwaitingCount > 0 || _rwaitingCount > 0 )
{
/*
* 如果在占有互斥量_stLock的情况下,触发事件,那么可能会使一些锁请求不能得到竞争机会.
* 假设调用unlock时,另一个线程正好调用rlock或者wlock.如果不释放互斥量,只有之前已经等待的锁请求有机会获得锁控制权.
*/
SetEvent(_ev);
}
else
{
/* 空闲 */
}
}
//ReleaseMutex(_stLock);
LeaveCriticalSection(&_stLock);
}
0 0
- 读写锁_用互斥和事件实现
- 多线程_普通锁和读写锁
- 读写锁和普通实现实现多线程读写者
- [并发并行]_[中级]_[实现Pthread线程并发读写锁rwlock]
- selec/poll中的读写事件和epoll中的读写事件
- 互斥锁和条件变量实现读写锁
- 使用互斥锁和条件变量实现实现读写锁
- GridView/DataGrid行单击和双击事件实现代码_.Net教程
- .NET组件程序设计 第8章 多线程和并发管理 同步线程_互锁,读写锁
- 线程间_读写锁属性
- Java多线程高级_读写锁
- 事件_内存和性能-读书笔记五
- 黑马程序员_委托和事件
- c++多线程读写窗体控件_自定义消息的实现
- c++多线程读写窗体控件_自定义消息的实现
- c++多线程读写窗体控件_自定义消息的实现
- Win32 实现读写锁
- 读写锁的实现!
- 日志 - 打印函数的调用过程
- iOS 远程消息推送 APNS推送原理和一步一步开发详解篇(新手推荐)
- zzulioj 1899(985的最大和难题)
- 日志 - 执行时间
- java编程思想 bruce Eckel chapter5 初始化与清理
- 读写锁_用互斥和事件实现
- 上下文管理 with 语句
- 纯CSS设置Checkbox复选框控件的样式
- 深拷贝 和 浅拷贝
- SDUT1075Doubles
- spring mvc +hibernate +spring +shiro 实现权限管理详细配置
- POJ 1236 Network of Schools(使DAG强联通最小加边数)
- 时间计算
- POJ 2983 Is the Information Reliable?(差分约束)