使用条件变量实现读写锁
cpp
// 思路:
// 信号量和互斥锁的搭配进行读写锁的设计:
//读锁:
// 请求读锁时,如果writer是false,说明现在无写者,因此可以读者++
// 释放读锁,--读者,当读者为0的时候,通知写者可以获取锁了
// 写锁:
// 写者加锁,等待reader为0把writer设设置true;
// 释放写锁:加锁: writer设置为false;然后通知读条件变量和写条件变量进行
class RWlock{
public:
RWlock():readers(0), writer(false){}
void acquireReadLock(){
// 请求读锁
std::unique_lock<std::mutex> lock(mutexlock);
readcondition.wait(lock, [this](){
return !writer;
});
++readers;
}
void releaseReadLock(){
std::unique_lock<std::mutex> lock(mutexlock);
--readers;
if(readers == 0){
// 没有读者了,通知写者进行开始工作了
writerCondition.notify_one(); // 由于读者不会因为这个原因卡。
}
}
void acquireWriteLock(){
std::unique_lock<std::mutex> lock(mutexlock);
writerCondition.wait(lock, [this](){return readers == 0;});
writer = true;
}
void releaseWriteLock(){
std::unique_lock<std::mutex> lock(mutexlock);
writer = false;
readcondition.notify_all();
// 也就是说条件变量必须通知
writerCondition.notify_one();
}
private:
std::mutex mutexlock;
std::condition_variable readcondition;
std::condition_variable writerCondition;
int readers = 0;
bool writer = false;
};
使用两个互斥锁实现读写锁
cpp
#include<iostream>
#include <thread>
#include <mutex>
// 思路是:
// 读者使用计数器计数,等到readcount == 1的时候写者锁上
// readcount == 0 的时候,写者解锁。
class ReadWriteLock{
public:
ReadWriteLock():readCount(0){}
void acquireReadLock(){
std::unique_lock<std::mutex> lock(readMutex);
++readCount;
if(readCount == 1){
// 存在读者就将write上锁
writeMutex.lock(); // 不允许写者加锁写者上锁
}
}
void releaseReadLock(){
// 这个怎么进行释放呢
std::unique_lock<std::mutex> lock(readMutex);
--readCount;
if(readCount == 0){
writeMutex.unlock(); // 允许读者加锁
}
}
// 实现写锁
void acquireWriteLock(){
// 如何获取写锁
writeMutex.lock();
}
void releaseWriteLock(){
writeMutex.unlock();
}
private:
std::mutex readMutex;
std::mutex writeMutex;
int readCount;
};
实现写优先
cpp
class ReadWriteLock{
public:
ReadWriteLock():readCount(0), writeCount(0){}
void acquireReadLock(){
std::unique_lock<std::mutex> lock(mutexLock);
readCondition.wait(lock, [this](){
return writeCount == 0;
});
++readCount;
}
void releaseReadLock(){
std::unique_lock<std::mutex> lock(mutexLock);
--readCount;
if(readCount == 0){// 写者被唤醒
writeCondition.notify_one();
}
}
void acquireWriteLock(){
std::unique_lock<std::mutex> lock(mutexLock);
++writeCount;
writeCondition.wait(lock, [this](){return readCount == 0 and !isWriting;});
isWriting = true;
}
void releaseWriteLock(){
std::unique_lock<std::mutex> lock(mutexLock);
--writeCount;
isWriting = false;
readCondition.notify_all();
writeCondition.notify_one();
}
private:
std::mutex mutexLock;
std::condition_variable readCondition;
std::condition_variable writeCondition;
int readCount = 0;
int writeCount = 0;
bool isWriting;
};