#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 here
ReadWriteLock 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 threads
for (int i = 0; i < numReaders; ++i) {
readerThreads[i].join();
}
for (int i = 0; i < numWriters; ++i) {
writerThreads[i].join();
}
return 0;
}
C++ WINDOWS XP系统 读写锁
于 2023-11-07 19:59:57 首次发布