参考网上资料,实现了一个读写锁,写优先。使用起来也很简单。
使用:
//先定义一个全局锁对象
tg_rwlock g_rwlock;
void test()
{
{
tg_rwlock::read_guard(g_rwlock);
//读..........
}
{
tg_rwlock::write_guard(g_rwlock);
//写..........
}
}
tg_rwlock.h
#ifndef TG_RWLOCK_H
#define TG_RWLOCK_H
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <memory>
class tg_rwguard;
class tg_rwlock
{
friend tg_rwguard;
private:
std::atomic<uint32_t> _read_cnt{ 0 };
std::atomic<uint32_t> _write_cnt{ 0 };
std::atomic<bool> _is_writing{false};
std::mutex _mutex;
std::condition_variable _read_cond;
std::condition_variable _write_cond;
public:
tg_rwlock() = default;
~tg_rwlock() = default;
static std::shared_ptr<tg_rwguard> read_guard(tg_rwlock& rwlock)
{
return std::make_shared<tg_rwguard>(rwlock, true);
}
static std::shared_ptr<tg_rwguard> write_guard(tg_rwlock& rwlock)
{
return std::make_shared<tg_rwguard>(rwlock, false);
}
private:
void rlock()
{
std::unique_lock<std::mutex> lock(_mutex);
_read_cond.wait(lock, [=] {return _write_cnt == 0; });
++_read_cnt;
}
void wlock()
{
std::unique_lock<std::mutex> lock(_mutex);
++_write_cnt;
_write_cond.wait(lock, [=] {return _read_cnt == 0 && !_is_writing; });
_is_writing = true;
}
void runlock()
{
std::unique_lock<std::mutex> lock(_mutex);
if (_read_cnt>0 && --_read_cnt == 0 && _write_cnt > 0)
{
_write_cond.notify_one();
}
}
void wunlock()
{
std::unique_lock<std::mutex> lock(_mutex);
if(_write_cnt < 1)
{
return;
}
if (--_write_cnt == 0)
{
_read_cond.notify_all();
}
else
{
_write_cond.notify_one();
_is_writing = false;
}
}
};
class tg_rwguard
{
public:
explicit tg_rwguard(tg_rwlock &rwlock, bool is_read) : _rwlock(rwlock),_is_read(is_read)
{
if(_is_read)
{
_rwlock.rlock();
}
else
{
_rwlock.wlock();
}
}
~tg_rwguard()
{
if(_is_read)
{
_rwlock.runlock();
}
else
{
_rwlock.wunlock();
}
}
private:
tg_rwguard() = delete;
tg_rwguard(const tg_rwguard&) = delete;
tg_rwguard& operator=(const tg_rwguard&) = delete;
private:
tg_rwlock& _rwlock;
bool _is_read;
};
#endif // TG_RWLOCK_H