在Win32平台中,多读单写锁如何使用临界区实现?
来源:互联网 发布:微信兵工厂软件 编辑:程序博客网 时间:2024/05/23 23:03
--------------------------------------------------------------------------------
标题: 在Win32平台中,多读单写锁如何使用临界区实现?
作者: 叶飞虎
日期: 2011.11.11
--------------------------------------------------------------------------------
在多线程编程中,读写锁主要应用于写数据相对比较少,而读比较多,同时要求并发性
比较高的时候。
现给出使用临界区的读写锁代码,如下:
class TKYLockRWEx{public: TKYLockRWEx(); virtual ~TKYLockRWEx(); bool LockRead(); bool LockWrite(); bool TryLockRead(); bool TryLockWrite(); void UnlockRead(); void UnlockWrite();private: void Lock() { EnterCriticalSection(&FRWLock); } void Unlock() { LeaveCriticalSection(&FRWLock); } void WaitingReader() { EnterCriticalSection(&FLockReader); } void WaitingWriter() { EnterCriticalSection(&FLockWriter); } inline void SetReadSignal(); inline void SetWriteSignal();private: CRITICAL_SECTION FRWLock; CRITICAL_SECTION FLockReader; CRITICAL_SECTION FLockWriter; long FReadingCount; long FWritingCount; long FWaitingReadCount; long FWaitingWriteCount;};// ---------------- 构造函数和析构函数 ----------------// 构造函数TKYLockRWEx::TKYLockRWEx(){ // 初始化 FReadingCount = 0; FWritingCount = 0; FWaitingReadCount = 0; FWaitingWriteCount= 0; // 创建临界区和读写者 InitializeCriticalSection(&FRWLock); InitializeCriticalSection(&FLockReader); InitializeCriticalSection(&FLockWriter);}// 析构函数TKYLockRWEx::~TKYLockRWEx(){ // 置释放标志 Lock(); bool bWaiting = (FReadingCount > 0) || (FWritingCount == 1) || (FWaitingReadCount > 0) || (FWaitingWriteCount > 0); FReadingCount = -1; Unlock(); // 等待一会儿 if (bWaiting) Sleep(10); // 释放临界区和读写者 DeleteCriticalSection(&FLockWriter); DeleteCriticalSection(&FLockReader); DeleteCriticalSection(&FRWLock);}// ---------------- 私有方法 ----------------// 设置读信号inline void TKYLockRWEx::SetReadSignal(){ // FWritingCount 作为读信号广播的个数 if (FWritingCount == 0) FWritingCount = -FWaitingReadCount; // 是否需要继续广播 if (FWritingCount < 0) { FWritingCount++; FReadingCount++; FWaitingReadCount--; LeaveCriticalSection(&FLockReader); } else if (FWaitingWriteCount == 0) // 全部已退出锁 { LeaveCriticalSection(&FLockReader); LeaveCriticalSection(&FLockWriter); }}// 设置写信号inline void TKYLockRWEx::SetWriteSignal(){ FWritingCount = 1; FWaitingWriteCount--; LeaveCriticalSection(&FLockWriter);}// ---------------- 公有方法 ----------------// 读加锁bool TKYLockRWEx::LockRead(){ bool result = true; bool bWaiting = false; // 读数加 1 Lock(); if (FReadingCount == -1) // 释放标志 result = false; else if ((FWritingCount == 1) || (FWaitingWriteCount > 0)) { FWaitingReadCount++; bWaiting = true; } else if (++FReadingCount == 1) { WaitingWriter(); WaitingReader(); } Unlock(); // 判断是否等待读信号 if (bWaiting) { // 等待读信号 WaitingReader(); // 若广播个数不为零则继续置信号 Lock(); if (FWritingCount < 0) SetReadSignal(); Unlock(); } // 返回结果 return result;}// 写加锁bool TKYLockRWEx::LockWrite(){ bool result = true; bool bWaiting = false; // 写数置 1 Lock(); if (FReadingCount == -1) // 释放标志 result = false; else if ((FWritingCount == 1) || (FReadingCount > 0)) { FWaitingWriteCount++; bWaiting = true; } else { FWritingCount = 1; WaitingWriter(); WaitingReader(); } Unlock(); // 判断是否等待写信号 if (bWaiting) WaitingWriter(); // 返回结果 return result;}// 读试着加锁bool TKYLockRWEx::TryLockRead(){ bool result = true; // 读数加 1 Lock(); if ((FReadingCount == -1) || (FWritingCount == 1) || (FWaitingWriteCount > 0)) result = false; else if (++FReadingCount == 1) { WaitingWriter(); WaitingReader(); } Unlock(); // 返回结果 return result;}// 写试着加锁bool TKYLockRWEx::TryLockWrite(){ bool result = true; // 写数置 1 Lock(); if ((FReadingCount == -1) || (FWritingCount == 1) || (FReadingCount > 0)) result = false; else { FWritingCount = 1; WaitingWriter(); WaitingReader(); } Unlock(); // 返回结果 return result;}// 读解锁void TKYLockRWEx::UnlockRead(){ Lock(); if (FReadingCount > 0) { // 读数减 1 FReadingCount--; // 置读/写信号 if (FReadingCount == 0) { if (FWaitingWriteCount > 0) SetWriteSignal(); else SetReadSignal(); } } Unlock();}// 写解锁void TKYLockRWEx::UnlockWrite(){ Lock(); if (FWritingCount == 1) { // 写数置 0 FWritingCount = 0; // 置读/写信号 if (FWaitingWriteCount > FWaitingReadCount) SetWriteSignal(); else SetReadSignal(); } Unlock();}
注:
使用临界区的读写锁代码是从使用 Event 的 TKYLockRW 类更改而来, 未经验证是否正
确, 本人只是从逻辑上确认没有bug, 倘若真的存在 bug, 欢迎拍砖指正!
- 在Win32平台中,多读单写锁如何使用临界区实现?
- 在Win32平台中,多读单写锁如何实现?
- Win32 临界区实现原理浅析
- Win32 临界区实现原理浅析
- 如何在win32 Application 中使用MFC
- 如何在win32工程中使用控制台
- win32临界代码段使用
- 为Win32建立临界区
- 如何在C#中使用 Win32和其他库
- (GDI+) 如何在 MFC 或 Win32 应用程序中使用GDI+
- 如何在C#中使用Win32和其他库
- 如何在C#中使用Win32和其他库
- 如何在C#中使用 Win32和其他库 (转)
- 如何在C#中使用 Win32和其他库
- 如何在C#中使用 Win32和其他库
- 如何在C#中使用Win32和其他库
- 如何在C#中使用Win32和其他库
- 如何在C#中使用 Win32和其他库
- java基础知识09
- 正则表达式1
- 不使用for完成一段有空格间隔的字符串,分辨长度大于等于4的单词(求各位高人修改,我表示我是菜鸟,这个算法实在太长了)
- linux目录意义
- Oracle笔记
- 在Win32平台中,多读单写锁如何使用临界区实现?
- IT运维管理和传统的网络管理的区别
- C++沉思录读书笔记(31章)- C++对复杂性的哲学
- 开篇——初出茅庐
- at91rm9200启动过程
- IT运维管理与ITIL
- Perl 闭包实现简单OO
- 求2进制数中1的个数
- 链表反转