键值对读写锁

一种键值对读写锁的尝试

博主在实际工作中,遇到这么一种场景:
前台向后台下发指令,后台根据指令执行轮询任务,每条任务之间相互独立。在到达轮询周期时,读取内存中最新的指令,进行任务,同时,前台可能在任意时刻对某条任务的指令数据进行修改,这时,很明显,需要一个读写锁。但是普通的读写锁,需要是全局的,并且锁的时候会把所有的整个数据全锁住,如博主用的map,而这个时候我只是想要对某个键值对的数据进行读写锁保护,所以便有了如下尝试。

定义可拷贝锁对象

因为mutex和condition_variable都是不可以拷贝的,所以这里进行简单的封装,通过不断的new和delete进行。

#include <mutex>
#include <condition_variable>

class RWLock{
public:
	RWLock() :  readCount(0),
				writeCount(0),
				isWriting(false){
		lock = new std::mutex();
		readCnd = new std::condition_variable();
		writeCnd = new std::condition_variable();
	}
	
	RWLock(const RWLock& rwlock){
		readCount = rwlock.readCount;
		writeCount = rwlock.writeCount;
		isWriting = rwlock.isWriting;
		readCnd = rwlock.readCnd;
		writeCnd = rwlock.writeCnd;
	}

	RWLock& operator=(const RWLock& rwlock){
		return *this;
	}

	virtual ~RWLock(){
		delete lock;
		delete readCnd;
		delete writeCnd;
	}

	void lockWrite(){
		std::unique_lock<std::mutex> gud(*lock);
		++writeCount;
		writeCnd->wait(gud, [=]{
			return (0 == readCount) && !isWriting;
		});
		
		isWriting = true;
	}

	void unlockWrite(){
		std::unique_lock<std::mutex> gud(*lock);
		isWriting = false;
		if(0 == (--writeCount)){
			readCnd->notify_all();
		}else{
			writeCnd->notify_one();
		}
	}

	void lockRead(){
		std::unique_lock<std::mutex> gud(*lock);
		readCnd->wait(gud, [=]{
			return 0 == writeCount;
		});
		--readCount;
	}

	void unlockRead(){
		std::unique_lock<std::mutex> gud(*lock);
		readCnd->wait(gud, [=]{
			return 0 == writeCount;
		});
		++readCount;
	}
private:
	volatile int readCount;
	volatile int writeCount;
	volatile bool isWriting;
	std::mutex *lock;
	std::condition_variable *readCnd;
	std::condition_variable *writeCnd;
}

写锁


class WriteGud{
public:
	explicit WriteGud(RWLock& rwlock) : lock(rwlock){
		lock.lockWrite();
	}
	
	virtual ~WriteGud(){
		lock.unlockWrite();
	}
private:
	WriteGud(const WriteGud&);
	WriteGud& operator=(const WriteGud&);
	RWLock& lock;
}

读锁


class ReadGud{
public:
	explicit ReadGud(RWLock& rwlock) : lock(rwlock){
		lock.lockRead();
	}
	
	virtual ~ReadGud(){
		lock.unlockRead();
	}
private:
	ReadGud(const ReadGud&);
	ReadGud& operator=(const ReadGud&);
	RWLock& lock;
}

使用

std::map<RWLock, Data> mData;
RWLock rwlock;
Data data;
mData[rwlock] =  data;

int getData(){
	ReadGud readgud(rwlock);
	...
}

int setData(){
	WriteGud writegud(rwlock);
	...
}

说明

这只是学习过程中的一种尝试,没有进行过测试,如果有问题,请不吝指教,我将万分感谢。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值