• C++ WINDOWS XP系统 读写锁


    参考libuv库:The Windows SRWLock primitive can be used for rw locking instead of a custom CRITICAL_SECTION+Semaphore implementation #3382 by dmachaj · Pull Request #3383 · libuv/libuv · GitHub 

    1. #include
    2. #include
    3. #include
    4. #include
    5. class ReadWriteLock {
    6. public:
    7. ReadWriteLock() {
    8. /* Initialize the semaphore that acts as the write lock. */
    9. HANDLE handle = CreateSemaphoreW(NULL, 1, 1, NULL);
    10. if (handle == NULL)
    11. {
    12. std::cout << "init error\n";
    13. // return uv_translate_sys_error(GetLastError());
    14. }
    15. m_write_semaphore = handle;
    16. /* Initialize the critical section protecting the reader count. */
    17. InitializeCriticalSection(&m_num_readers_lock);
    18. /* Initialize the reader count. */
    19. m_num_readers = 0;
    20. }
    21. ~ReadWriteLock() {
    22. DeleteCriticalSection(&m_num_readers_lock);
    23. CloseHandle(m_write_semaphore);
    24. }
    25. bool TryReadLock()
    26. {
    27. bool err;
    28. if (!TryEnterCriticalSection(&m_num_readers_lock))
    29. {
    30. std::cout << "TryEnterCriticalSection error\n";
    31. return false;
    32. }
    33. err = true;
    34. if (m_num_readers == 0) {
    35. /* Currently there are no other readers, which means that the write lock
    36. * needs to be acquired.
    37. */
    38. DWORD r = WaitForSingleObject(m_write_semaphore, 0);
    39. if (r == WAIT_OBJECT_0)
    40. m_num_readers++;
    41. else if (r == WAIT_TIMEOUT)
    42. {
    43. std::cout << "try read lock WAIT_TIMEOUT error\n";
    44. err = false;
    45. }
    46. else if (r == WAIT_FAILED)
    47. {
    48. std::cout << "fatal! try read lock\n";
    49. //uv_fatal_error(GetLastError(), "WaitForSingleObject");
    50. err = false;
    51. }
    52. }
    53. else {
    54. /* The write lock has already been acquired because there are other
    55. * active readers.
    56. */
    57. m_num_readers++;
    58. }
    59. LeaveCriticalSection(&m_num_readers_lock);
    60. return err;
    61. }
    62. void ReadLock() {
    63. /* Acquire the lock that protects the reader count. */
    64. EnterCriticalSection(&m_num_readers_lock);
    65. /* Increase the reader count, and lock for write if this is the first
    66. * reader.
    67. */
    68. if (++m_num_readers == 1) {
    69. DWORD r = WaitForSingleObject(m_write_semaphore, INFINITE);
    70. if (r != WAIT_OBJECT_0)
    71. {
    72. std::cout << "read lock error\n";
    73. //uv_fatal_error(GetLastError(), "WaitForSingleObject");
    74. }
    75. }
    76. /* Release the lock that protects the reader count. */
    77. LeaveCriticalSection(&m_num_readers_lock);
    78. }
    79. void ReadUnlock() {
    80. EnterCriticalSection(&m_num_readers_lock);
    81. if (--m_num_readers == 0) {
    82. if (!ReleaseSemaphore(m_write_semaphore, 1, NULL))
    83. {
    84. std::cout << "read unlock error\n";
    85. //uv_fatal_error(GetLastError(), "ReleaseSemaphore");
    86. }
    87. }
    88. LeaveCriticalSection(&m_num_readers_lock);
    89. }
    90. bool TryWriteLock()
    91. {
    92. DWORD r = WaitForSingleObject(m_write_semaphore, 0);
    93. if (r == WAIT_OBJECT_0)
    94. {
    95. std::cout << "try write lock success\n";
    96. return true;
    97. }
    98. else if (r == WAIT_TIMEOUT)
    99. {
    100. std::cout << "try write lock WAIT_TIMEOUT\n";
    101. return false;
    102. }
    103. else
    104. {
    105. std::cout << "try write lock fatal\n";
    106. return false;
    107. //uv_fatal_error(GetLastError(), "WaitForSingleObject");
    108. }
    109. }
    110. void WriteLock() {
    111. DWORD r = WaitForSingleObject(m_write_semaphore, INFINITE);
    112. if (r != WAIT_OBJECT_0)
    113. {
    114. std::cout << "write lock error\n";
    115. //uv_fatal_error(GetLastError(), "WaitForSingleObject");
    116. }
    117. else
    118. {
    119. std::cout << "get write lock\n";
    120. }
    121. }
    122. void WriteUnlock() {
    123. if (!ReleaseSemaphore(m_write_semaphore, 1, NULL))
    124. {
    125. std::cout << "ReleaseSemaphore error: " << GetLastError();
    126. //uv_fatal_error(GetLastError(), "ReleaseSemaphore");
    127. }
    128. std::cout << "write unlock\n";
    129. }
    130. private:
    131. unsigned int m_num_readers;
    132. CRITICAL_SECTION m_num_readers_lock;
    133. HANDLE m_write_semaphore;
    134. };
    135. #include
    136. #include
    137. #include
    138. #include
    139. #include
    140. #include
    141. // Include your ReadWriteLock class definition here
    142. ReadWriteLock rwLock;
    143. std::map<int,std::string> g_map;
    144. void ReaderThread(int id) {
    145. int i = 0;
    146. while (i < 100) {
    147. if (rwLock.TryReadLock())
    148. {
    149. //rwLock.ReadLock();
    150. //
    151. std::cout << "read: " << g_map[g_map.size() - 1] << std::endl;
    152. //
    153. rwLock.ReadUnlock();
    154. }
    155. else
    156. {
    157. std::cout << "try read lock error!\n";
    158. }
    159. //
    160. std::this_thread::sleep_for(std::chrono::milliseconds(100));
    161. //
    162. i++;
    163. }
    164. }
    165. void WriterThread(int id) {
    166. int i = 0;
    167. while (i < 100) {
    168. if (rwLock.TryWriteLock())
    169. {
    170. //rwLock.WriteLock();
    171. //
    172. g_map[g_map.size() + 1] = std::to_string(g_map.size()) + "_value";
    173. std::cout << "write: " << g_map.size() << std::endl;
    174. //
    175. rwLock.WriteUnlock();
    176. }
    177. else
    178. {
    179. std::cout << "try write lock error!\n";
    180. }
    181. std::this_thread::sleep_for(std::chrono::milliseconds(10));
    182. //
    183. i++;
    184. }
    185. }
    186. int main() {
    187. g_map[0] = "init";
    188. const int numReaders = 10;
    189. const int numWriters = 1;
    190. std::vector readerThreads;
    191. std::vector writerThreads;
    192. for (int i = 0; i < numReaders; ++i) {
    193. readerThreads.emplace_back(ReaderThread, i);
    194. }
    195. for (int i = 0; i < numWriters; ++i) {
    196. writerThreads.emplace_back(WriterThread, i);
    197. }
    198. // Join all the threads
    199. for (int i = 0; i < numReaders; ++i) {
    200. readerThreads[i].join();
    201. }
    202. for (int i = 0; i < numWriters; ++i) {
    203. writerThreads[i].join();
    204. }
    205. return 0;
    206. }

  • 相关阅读:
    java计算机毕业设计智慧问诊系统源码+数据库+系统+lw文档
    常见的设计模式
    VSCODE include错误 找不到 stdio.h
    SpringBoot SpringBoot 运维实用篇 3 多环境开发 3.1 多环境开发【yaml版】
    利用Python和Selenium编程,实现定时自动检索特定网页,发现特定网页内容发生变化后,向管理员发送提醒邮件(一)
    J2EE项目部署与发布(Windows版本)
    一些移动端开发技巧
    SAP abap ALV 自定义按钮功能
    【Java刷题进阶】基础入门篇⑤
    SpringCloud Sleuth+Zipkin
  • 原文地址:https://blog.csdn.net/qq_41221841/article/details/134274968