文章转自:http://blog.youkuaiyun.com/mymodian9612/article/details/52794980
先直接贴出代码:
#ifndef __WRITE_FIRST_RW_LOCK_H
#define __WRITE_FIRST_RW_LOCK_H
#include <mutex>
#include <condition_variable>
class WfirstRWLock
{
public:
WfirstRWLock() = default;
~WfirstRWLock() = default;
public:
void lock_read()
{
std::unique_lock<std::mutex> ulk(counter_mutex);
cond_r.wait(ulk, [=]()->bool {return write_cnt == 0; });
++read_cnt;
}
void lock_write()
{
std::unique_lock<std::mutex> ulk(counter_mutex);
++write_cnt;
cond_w.wait(ulk, [=]()->bool {return read_cnt == 0 && !inwriteflag; });
inwriteflag = true;
}
void release_read()
{
std::unique_lock<std::mutex> ulk(counter_mutex);
if (--read_cnt == 0 && write_cnt > 0)
{
cond_w.notify_one();
}
}
void release_write()
{
std::unique_lock<std::mutex> ulk(counter_mutex);
if (--write_cnt == 0)
{
cond_r.notify_all();
}
else
{
cond_w.notify_one();
}
inwriteflag = false;
}
private:
volatile size_t read_cnt{ 0 };
volatile size_t write_cnt{ 0 };
volatile bool inwriteflag{ false };
std::mutex counter_mutex;
std::condition_variable cond_w;
std::condition_variable cond_r;
};
template <typename _RWLockable>
class unique_writeguard
{
public:
explicit unique_writeguard(_RWLockable &rw_lockable)
: rw_lockable_(rw_lockable)
{
rw_lockable_.lock_write();
}
~unique_writeguard()
{
rw_lockable_.release_write();
}
private:
unique_writeguard() = delete;
unique_writeguard(const unique_writeguard&) = delete;
unique_writeguard& operator=(const unique_writeguard&) = delete;
private:
_RWLockable &rw_lockable_;
};
template <typename _RWLockable>
class unique_readguard
{
public:
explicit unique_readguard(_RWLockable &rw_lockable)
: rw_lockable_(rw_lockable)
{
rw_lockable_.lock_read();
}
~unique_readguard()
{
rw_lockable_.release_read();
}
private:
unique_readguard() = delete;
unique_readguard(const unique_readguard&) = delete;
unique_readguard& operator=(const unique_readguard&) = delete;
private:
_RWLockable &rw_lockable_;
};
#endif
可以看出用c++11实现读写锁变得非常简洁,在读取量非常大且写入频率很低的时候,通过一个简单的写入线程计数可以避免大量的 cond_w.notify_one();减少读取线程因此发生的切换。
这里需要注意的是对写操作加锁时是先增加写线程计数再判断条件并等待,释放写锁时减少写线程计数并判断是否还有写操作等待,如果有只能唤醒一个写等待。
另外,直接使用lock、unlock在c++中是不推荐的,推荐采用RAII方法,即类unique_writeguard、unique_readguard。

本文介绍了一种基于C++11标准库实现的读写锁,该实现利用了互斥量和条件变量来确保多线程环境中读取和写入操作的正确性。在读取操作频繁而写入操作较少的情况下,这种实现能够有效减少不必要的线程切换,提高系统的整体性能。
7729

被折叠的 条评论
为什么被折叠?



