123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- //-----------------------------------------------------------------------------
- // 用共享锁实现的并发共享数据的模板类. 比排他锁的性能要高很多.
- // 适用于多读少写的场景
- //
- // 特别要注意, 不能递归使用 !!! 不能递归使用 !!! 不能递归使用 !!! 否则会死锁 !
- //
- // 不是 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 <memory>
- #include <shared_mutex>
- //-----------------------------------------------------------------------------
- // SharedMutexHolder.tlh
- // 允许互斥访问一个指针对象, 但是是用共享锁实现. 比排他锁的性能要高很多
- //-----------------------------------------------------------------------------
- template <typename T> 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 <typename C> C * AS ();
- template <typename C> 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 <typename C> C * AS ();
- template <typename C> 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 <T> & 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 <T>& with)
- {
- auto tmp = with.release ();
- with.reset (this->m_pObject);
- this->m_pObject = tmp;
- }
- };
|