参考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
HANDLE handle = CreateSemaphoreW(NULL, 1, 1, NULL);
std::cout << "init error\n";
m_write_semaphore = handle;
InitializeCriticalSection(&m_num_readers_lock);
DeleteCriticalSection(&m_num_readers_lock);
CloseHandle(m_write_semaphore);
if (!TryEnterCriticalSection(&m_num_readers_lock))
std::cout << "TryEnterCriticalSection error\n";
if (m_num_readers == 0) {
DWORD r = WaitForSingleObject(m_write_semaphore, 0);
else if (r == WAIT_TIMEOUT)
std::cout << "try read lock WAIT_TIMEOUT error\n";
else if (r == WAIT_FAILED)
std::cout << "fatal! try read lock\n";
LeaveCriticalSection(&m_num_readers_lock);
EnterCriticalSection(&m_num_readers_lock);
if (++m_num_readers == 1) {
DWORD r = WaitForSingleObject(m_write_semaphore, INFINITE);
std::cout << "read lock error\n";
LeaveCriticalSection(&m_num_readers_lock);
EnterCriticalSection(&m_num_readers_lock);
if (--m_num_readers == 0) {
if (!ReleaseSemaphore(m_write_semaphore, 1, NULL))
std::cout << "read unlock error\n";
LeaveCriticalSection(&m_num_readers_lock);
DWORD r = WaitForSingleObject(m_write_semaphore, 0);
std::cout << "try write lock success\n";
else if (r == WAIT_TIMEOUT)
std::cout << "try write lock WAIT_TIMEOUT\n";
std::cout << "try write lock fatal\n";
DWORD r = WaitForSingleObject(m_write_semaphore, INFINITE);
std::cout << "write lock error\n";
std::cout << "get write lock\n";
if (!ReleaseSemaphore(m_write_semaphore, 1, NULL))
std::cout << "ReleaseSemaphore error: " << GetLastError();
std::cout << "write unlock\n";
unsigned int m_num_readers;
CRITICAL_SECTION m_num_readers_lock;
HANDLE m_write_semaphore;
std::map<int,std::string> g_map;
void ReaderThread(int id) {
if (rwLock.TryReadLock())
std::cout << "read: " << g_map[g_map.size() - 1] << std::endl;
std::cout << "try read lock error!\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
void WriterThread(int id) {
if (rwLock.TryWriteLock())
g_map[g_map.size() + 1] = std::to_string(g_map.size()) + "_value";
std::cout << "write: " << g_map.size() << std::endl;
std::cout << "try write lock error!\n";
std::this_thread::sleep_for(std::chrono::milliseconds(10));
const int numReaders = 10;
const int numWriters = 1;
std::vector readerThreads;
std::vector 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);
for (int i = 0; i < numReaders; ++i) {
for (int i = 0; i < numWriters; ++i) {