SharedMutexHolder.tlh 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. //-----------------------------------------------------------------------------
  2. // 用共享锁实现的并发共享数据的模板类. 比排他锁的性能要高很多.
  3. // 适用于多读少写的场景
  4. //
  5. // 特别要注意, 不能递归使用 !!! 不能递归使用 !!! 不能递归使用 !!! 否则会死锁 !
  6. //
  7. // 不是 dll, 没有版本号, 因此要手工编写版本号
  8. // V1, 2022-01-23
  9. // V2, 2022-10-28, LockHolder 中, 删除 std::unique_ptr, 直接用
  10. // std::lock_guard < std::shared_mutex > m_Lock (for update)
  11. // 或者
  12. // std::shared_lock < std::shared_mutex > (for read)
  13. // 这样可以避免一次 new / delete
  14. //-----------------------------------------------------------------------------
  15. #pragma once
  16. #include <memory>
  17. #include <shared_mutex>
  18. //-----------------------------------------------------------------------------
  19. // SharedMutexHolder.tlh
  20. // 允许互斥访问一个指针对象, 但是是用共享锁实现. 比排他锁的性能要高很多
  21. //-----------------------------------------------------------------------------
  22. template <typename T> class SharedMutexHolder
  23. {
  24. protected:
  25. T * m_pObject;
  26. public:
  27. SharedMutexHolder ();
  28. explicit SharedMutexHolder (T * object);
  29. virtual ~SharedMutexHolder ();
  30. private:
  31. // 禁止拷贝构造函数
  32. SharedMutexHolder (const SharedMutexHolder & h) = delete;
  33. // 禁止复制
  34. SharedMutexHolder & operator = (const SharedMutexHolder & h) = delete;
  35. public:
  36. void Attach (T * obj);
  37. T * Detach ();
  38. SharedMutexHolder & operator = (T * object);
  39. bool Update (T && obj);
  40. public:
  41. bool IsEmpty () const;
  42. operator bool () const { return m_pObject; }
  43. void Release ();
  44. protected:
  45. mutable std::shared_mutex m_Mutex;
  46. public:
  47. class ReadLock
  48. {
  49. public:
  50. ReadLock (const SharedMutexHolder * holder);
  51. ~ReadLock () = default;
  52. ReadLock (ReadLock && from);
  53. private:
  54. // 可以对同一个 SharedMutexHolder 对象反复调用 Lock, 但是 LockHolder 还是不要拷贝构造了吧
  55. // 禁止拷贝构造函数
  56. ReadLock (const ReadLock & h) = delete;
  57. // 禁止复制
  58. ReadLock& operator = (const ReadLock & h) = delete;
  59. public:
  60. T * As ();
  61. const T * As () const;
  62. template <typename C> C * AS ();
  63. template <typename C> const C * AS () const;
  64. T * operator -> ()
  65. {
  66. return As ();
  67. }
  68. const T * operator -> () const
  69. {
  70. return As ();
  71. }
  72. T & operator * ()
  73. {
  74. return *As ();
  75. }
  76. const T & operator * () const
  77. {
  78. return *As ();
  79. }
  80. operator bool () const
  81. {
  82. return As ();
  83. }
  84. protected:
  85. std::shared_lock < std::shared_mutex > m_Lock;
  86. const SharedMutexHolder * m_Holder;
  87. };
  88. public:
  89. class UpdateLock
  90. {
  91. public:
  92. UpdateLock (SharedMutexHolder * holder);
  93. ~UpdateLock () = default;
  94. UpdateLock (ReadLock && from);
  95. private:
  96. // 可以对同一个 SharedMutexHolder 对象反复调用 Lock, 但是 LockHolder 还是不要拷贝构造了吧
  97. // 禁止拷贝构造函数
  98. UpdateLock (const UpdateLock & h) = delete;
  99. // 禁止复制
  100. UpdateLock & operator = (const UpdateLock & h) = delete;
  101. public:
  102. T * As ();
  103. const T * As () const;
  104. template <typename C> C * AS ();
  105. template <typename C> const C * AS () const;
  106. T * operator -> ()
  107. {
  108. return As ();
  109. }
  110. const T * operator -> () const
  111. {
  112. return As ();
  113. }
  114. T & operator * ()
  115. {
  116. return *As ();
  117. }
  118. const T & operator * () const
  119. {
  120. return *As ();
  121. }
  122. operator bool () const
  123. {
  124. return As ();
  125. }
  126. protected:
  127. std::lock_guard < std::shared_mutex > m_Lock;
  128. SharedMutexHolder * m_Holder;
  129. };
  130. public:
  131. inline ReadLock WillRead ()
  132. {
  133. return ReadLock (this);
  134. }
  135. inline ReadLock WillRead () const
  136. {
  137. return ReadLock (this);
  138. }
  139. public:
  140. inline UpdateLock WillUpdate ()
  141. {
  142. return UpdateLock (this);
  143. }
  144. inline UpdateLock WillUpdate () const
  145. {
  146. return UpdateLock (this);
  147. }
  148. public:
  149. inline void InterlockedSwap (std::unique_ptr <T> & with)
  150. {
  151. auto tmp = with.release ();
  152. auto lock = WillUpdate ();
  153. with.reset (this->m_pObject);
  154. this->m_pObject = tmp;
  155. }
  156. inline void Swap (UpdateLock & lock, std::unique_ptr <T>& with)
  157. {
  158. auto tmp = with.release ();
  159. with.reset (this->m_pObject);
  160. this->m_pObject = tmp;
  161. }
  162. };