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 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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值