//----------------------------------------------------------------------------- // 用共享锁实现的并发共享数据的模板类. 比排他锁的性能要高很多. // 适用于多读少写的场景 // // 特别要注意, 不能递归使用 !!! 不能递归使用 !!! 不能递归使用 !!! 否则会死锁 ! // // 不是 dll, 没有版本号, 因此要手工编写版本号 // V1, 2022-01-23 // V2, 2022-10-28, LockHolder 中, 删除 std::unique_ptr, 直接用 // std::lock_guard < std::shared_mutex > m_Lock (for update) // 或者 // std::shared_lock < std::shared_mutex > (for read) // 这样可以避免一次 new / delete //----------------------------------------------------------------------------- #pragma once #include #include //----------------------------------------------------------------------------- // SharedMutexHolder.tlh // 允许互斥访问一个指针对象, 但是是用共享锁实现. 比排他锁的性能要高很多 //----------------------------------------------------------------------------- template class SharedMutexHolder { protected: T * m_pObject; public: SharedMutexHolder (); explicit SharedMutexHolder (T * object); virtual ~SharedMutexHolder (); private: // 禁止拷贝构造函数 SharedMutexHolder (const SharedMutexHolder & h) = delete; // 禁止复制 SharedMutexHolder & operator = (const SharedMutexHolder & h) = delete; public: void Attach (T * obj); T * Detach (); SharedMutexHolder & operator = (T * object); bool Update (T && obj); public: bool IsEmpty () const; operator bool () const { return m_pObject; } void Release (); protected: mutable std::shared_mutex m_Mutex; public: class ReadLock { public: ReadLock (const SharedMutexHolder * holder); ~ReadLock () = default; ReadLock (ReadLock && from); private: // 可以对同一个 SharedMutexHolder 对象反复调用 Lock, 但是 LockHolder 还是不要拷贝构造了吧 // 禁止拷贝构造函数 ReadLock (const ReadLock & h) = delete; // 禁止复制 ReadLock& operator = (const ReadLock & h) = delete; public: T * As (); const T * As () const; template C * AS (); template const C * AS () const; T * operator -> () { return As (); } const T * operator -> () const { return As (); } T & operator * () { return *As (); } const T & operator * () const { return *As (); } operator bool () const { return As (); } protected: std::shared_lock < std::shared_mutex > m_Lock; const SharedMutexHolder * m_Holder; }; public: class UpdateLock { public: UpdateLock (SharedMutexHolder * holder); ~UpdateLock () = default; UpdateLock (ReadLock && from); private: // 可以对同一个 SharedMutexHolder 对象反复调用 Lock, 但是 LockHolder 还是不要拷贝构造了吧 // 禁止拷贝构造函数 UpdateLock (const UpdateLock & h) = delete; // 禁止复制 UpdateLock & operator = (const UpdateLock & h) = delete; public: T * As (); const T * As () const; template C * AS (); template const C * AS () const; T * operator -> () { return As (); } const T * operator -> () const { return As (); } T & operator * () { return *As (); } const T & operator * () const { return *As (); } operator bool () const { return As (); } protected: std::lock_guard < std::shared_mutex > m_Lock; SharedMutexHolder * m_Holder; }; public: inline ReadLock WillRead () { return ReadLock (this); } inline ReadLock WillRead () const { return ReadLock (this); } public: inline UpdateLock WillUpdate () { return UpdateLock (this); } inline UpdateLock WillUpdate () const { return UpdateLock (this); } public: inline void InterlockedSwap (std::unique_ptr & with) { auto tmp = with.release (); auto lock = WillUpdate (); with.reset (this->m_pObject); this->m_pObject = tmp; } inline void Swap (UpdateLock & lock, std::unique_ptr & with) { auto tmp = with.release (); with.reset (this->m_pObject); this->m_pObject = tmp; } };