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
#include <iostream>
#include <vector>
#include <thread>
#include <Windows.h>class ReadWriteLock {
public:ReadWriteLock() {/* Initialize the semaphore that acts as the write lock. */HANDLE handle = CreateSemaphoreW(NULL, 1, 1, NULL);if (handle == NULL){std::cout << "init error\n";// return uv_translate_sys_error(GetLastError());}m_write_semaphore = handle;/* Initialize the critical section protecting the reader count. */InitializeCriticalSection(&m_num_readers_lock);/* Initialize the reader count. */m_num_readers = 0;}~ReadWriteLock() {DeleteCriticalSection(&m_num_readers_lock);CloseHandle(m_write_semaphore);}bool TryReadLock(){bool err;if (!TryEnterCriticalSection(&m_num_readers_lock)){std::cout << "TryEnterCriticalSection error\n";return false;}err = true;if (m_num_readers == 0) {/* Currently there are no other readers, which means that the write lock* needs to be acquired.*/DWORD r = WaitForSingleObject(m_write_semaphore, 0);if (r == WAIT_OBJECT_0)m_num_readers++;else if (r == WAIT_TIMEOUT){std::cout << "try read lock WAIT_TIMEOUT error\n";err = false;}else if (r == WAIT_FAILED){std::cout << "fatal! try read lock\n";//uv_fatal_error(GetLastError(), "WaitForSingleObject");err = false;}}else {/* The write lock has already been acquired because there are other* active readers.*/m_num_readers++;}LeaveCriticalSection(&m_num_readers_lock);return err;}void ReadLock() {/* Acquire the lock that protects the reader count. */EnterCriticalSection(&m_num_readers_lock);/* Increase the reader count, and lock for write if this is the first* reader.*/if (++m_num_readers == 1) {DWORD r = WaitForSingleObject(m_write_semaphore, INFINITE);if (r != WAIT_OBJECT_0){std::cout << "read lock error\n";//uv_fatal_error(GetLastError(), "WaitForSingleObject");}}/* Release the lock that protects the reader count. */LeaveCriticalSection(&m_num_readers_lock);}void ReadUnlock() {EnterCriticalSection(&m_num_readers_lock);if (--m_num_readers == 0) {if (!ReleaseSemaphore(m_write_semaphore, 1, NULL)){std::cout << "read unlock error\n";//uv_fatal_error(GetLastError(), "ReleaseSemaphore");}}LeaveCriticalSection(&m_num_readers_lock);}bool TryWriteLock(){DWORD r = WaitForSingleObject(m_write_semaphore, 0);if (r == WAIT_OBJECT_0){std::cout << "try write lock success\n";return true;}else if (r == WAIT_TIMEOUT){std::cout << "try write lock WAIT_TIMEOUT\n";return false;}else{std::cout << "try write lock fatal\n";return false;//uv_fatal_error(GetLastError(), "WaitForSingleObject");}}void WriteLock() {DWORD r = WaitForSingleObject(m_write_semaphore, INFINITE);if (r != WAIT_OBJECT_0){std::cout << "write lock error\n";//uv_fatal_error(GetLastError(), "WaitForSingleObject");}else{std::cout << "get write lock\n";}}void WriteUnlock() {if (!ReleaseSemaphore(m_write_semaphore, 1, NULL)){std::cout << "ReleaseSemaphore error: " << GetLastError();//uv_fatal_error(GetLastError(), "ReleaseSemaphore");}std::cout << "write unlock\n";}private:unsigned int m_num_readers;CRITICAL_SECTION m_num_readers_lock;HANDLE m_write_semaphore;
};#include <iostream>
#include <thread>
#include <vector>
#include <chrono>
#include <map>
#include <string>// Include your ReadWriteLock class definition hereReadWriteLock rwLock;
std::map<int,std::string> g_map;void ReaderThread(int id) {int i = 0;while (i < 100) {if (rwLock.TryReadLock()){//rwLock.ReadLock();//std::cout << "read: " << g_map[g_map.size() - 1] << std::endl;//rwLock.ReadUnlock();}else{std::cout << "try read lock error!\n";}//std::this_thread::sleep_for(std::chrono::milliseconds(100));//i++;}
}void WriterThread(int id) {int i = 0;while (i < 100) {if (rwLock.TryWriteLock()){//rwLock.WriteLock();//g_map[g_map.size() + 1] = std::to_string(g_map.size()) + "_value";std::cout << "write: " << g_map.size() << std::endl;//rwLock.WriteUnlock();}else{std::cout << "try write lock error!\n";}std::this_thread::sleep_for(std::chrono::milliseconds(10));//i++;}
}int main() {g_map[0] = "init";const int numReaders = 10;const int numWriters = 1;std::vector<std::thread> readerThreads;std::vector<std::thread> writerThreads;for (int i = 0; i < numReaders; ++i) {readerThreads.emplace_back(ReaderThread, i);}for (int i = 0; i < numWriters; ++i) {writerThreads.emplace_back(WriterThread, i);}// Join all the threadsfor (int i = 0; i < numReaders; ++i) {readerThreads[i].join();}for (int i = 0; i < numWriters; ++i) {writerThreads[i].join();}return 0;
}