扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
//基类: class RWLockBase //表示Read/Write Lock ...{ HANDLE* handles; protected: RWLockBase(int handleCount) ...{ handles = new HANDLE[handleCount]; } … }; //子类: class MyClass: public RWLockBase ...{ MyClass(): RWLockBase(3) ...{} … }; |
template <int maxReadCount> class RWLockBase ...{ HANDLE handles[maxReadCount]; … }; |
class _RWLockBase ...{ friend class RWLock; protected: virtual DWORD ReadLock(int timeout) = 0; virtual void ReadUnlock(int handleIndex) = 0; virtual DWORD WriteLock(int timeout) = 0; virtual void WriteUnlock() = 0; }; |
template <int maxReadCount = 3> //这里给一个缺省参数,尽量减少客户端代码量 class RWLockBase: public _RWLockBase ...{ HANDLE handles[maxReadCount]; DWORD ReadLock(int timeout) //加读锁,只要等到一个互斥量返回即可 ...{ return ::WaitForMultipleObjects(maxReadCount, handles, FALSE, timeout); } void ReadUnlock(int handleIndex) //解读锁,释放已获得的互斥量 ...{ ::ReleaseMutex(handles[handleIndex]); } DWORD WriteLock(int timeout) //加写锁,等到所有互斥量,从而与其他所有线程互斥 ...{ return ::WaitForMultipleObjects(maxReadCount, handles, TRUE, timeout); } void WriteUnlock() //解写锁,释放所有的互斥量 ...{ for(int i = 0; i < maxReadCount; i++) ::ReleaseMutex(handles[i]); } protected: WLockBase() //构造函数,初始化每个互斥量 ..{ for(int i = 0; i < maxReadCount; i++) handles[i] = ::CreateMutex(0, FALSE, 0); } ~RWLockBase() //析构函数,销毁对象 ...{ for(int i = 0; i < maxReadCount; i++) ::CloseHandle(handles[i]); } }; |
class RWLock ...{ bool lockSuccess; //因为有可能超时,需要保存是否等待成功 int readLockHandleIndex; //对于读锁,需要知道获得的是哪个互斥量 _RWLockBase* _pObj; //目标对象基类指针 public: //这里通过第二个参数决定是加读锁还是写锁,第三个参数为超时的时间 RWLock(_RWLockBase* pObj, bool readLock = true, int timeout = 3000) ...{ _pObj = pObj; lockSuccess = FALSE; readLockHandleIndex = -1; if(NULL == _pObj) return; if(readLock) //读锁 ...{ DWORD retval = _pObj->ReadLock(timeout); if(retval < WAIT_ABANDONED) //返回值小于WAIT_ABANDONED表示成功 ...{ //其值减WAIT_OBJECT_0就是数组下标 readLockHandleIndex = retval - WAIT_OBJECT_0; lockSuccess = TRUE; } } else ...{ WORD retval = _pObj->WriteLock(timeout); if(retval < WAIT_ABANDONED) //写锁时获得了所有互斥量,无需保存下标 lockSuccess = TRUE; } } ~RWLock() ...{ if(NULL == _pObj) return; if(readLockHandleIndex > -1) _pObj->ReadUnlock(readLockHandleIndex); else _pObj->WriteUnlock(); } bool IsLockSuccess() const ...{ return lockSuccess; } }; |
class MyClass2: public RWLockBase<> ...{}; MyClass2 mc2; |
//读线程 DWORD CALLBACK ReadThreadProc(LPVOID param) ...{ int i = (int)param; RWLock lock(&mc2); //加读锁 if(lock.IsLockSuccess()) //如果加锁成功 { Say("read thread %d started", i); //为了代码短一些,假设Say函数有这种能力 Sleep(1000); Say("read thread %d ended", i); } else //加锁超时,则显示超时信息 Say("read thread %d timeout", i); return 0; } //写线程 DWORD CALLBACK WriteThreadProc(LPVOID param) ...{ int i = (int)param; RWLock lock(&mc2, false); //加写锁。 if(lock.IsLockSuccess()) ...{ Say("write thread %d started", i); Sleep(600); Say("write thread %d ended", i); } else Say("write thread %d timeout", i); return 0; } |
int i; for(i = 0; i < 5; i++) ::CreateThread(0, 0, ReadThreadProc, (LPVOID)i, 0, 0); for(i = 0; i < 5; i++) ::CreateThread(0, 0, WriteThreadProc, (LPVOID)i, 0, 0); |
001 [15:07:28.484]read thread 0 started 002 [15:07:28.484]read thread 1 started 003 [15:07:28.484]read thread 2 started 004 [15:07:29.484]read thread 0 ended 005 [15:07:29.484]read thread 3 started 006 [15:07:29.484]read thread 1 ended 007 [15:07:29.484]read thread 4 started 008 [15:07:29.484]read thread 2 ended 009 [15:07:30.484]read thread 3 ended 010 [15:07:30.484]read thread 4 ended 011 [15:07:30.484]write thread 0 started 012 [15:07:31.078]write thread 0 ended 013 [15:07:31.078]write thread 1 started 014 [15:07:31.484]write thread 2 timeout 015 [15:07:31.484]write thread 3 timeout 016 [15:07:31.484]write thread 4 timeout 017 [15:07:31.687]write thread 1 ended |
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者