c++讀寫鎖-自實現

#ifndef _RWLOCK_H_
#define _RWLOCK_H_

#include <mutex>
#include <condition_variable>

// 讀寫互斥量
// 當有寫和讀操作同時競爭時,寫操作優先與讀操作
class CRWMutex
{
public:
	CRWMutex()
		: m_read_count_(0)
		, m_write_count_(0)
		, m_is_writing_(false)
	{
	}

	virtual ~CRWMutex() = default;

	void LockRead()
	{
		std::unique_lock<std::mutex> locker(m_mutex_);
		m_read_cond_.wait(locker, [=]{return 0 == m_write_count_; }); // 沒有寫等待時,可執行讀
		++m_read_count_;
	}

	void UnLockRead()
	{
		std::unique_lock<std::mutex> locker(m_mutex_);
		if (0 == --m_read_count_ && 0 != m_write_count_) // 當讀操作減爲0,並且有等待的寫操作時,通知一個線程寫
		{
			m_write_cond.notify_one();
		}
	}

	void LockWrite()
	{
		std::unique_lock<std::mutex> locker(m_mutex_);
		++m_write_count_;																//寫先進行計數統計,這裏可以實現寫優先於讀
		m_write_cond.wait(locker, [=]{return 0 == m_read_count_ && !m_is_writing_; });	// 沒有讀操作並且沒有正在寫時,可執行寫
		m_is_writing_ = true;
	}

	void UnLockWrite()
	{
		std::unique_lock<std::mutex> locker(m_mutex_);
		if (0 == --m_write_count_)
		{
			m_read_cond_.notify_all();		// 沒有寫操作等待時,通知所有讀
		}else
		{
			m_write_cond.notify_one();		// 還有寫操作等待時,通知一個線程寫
		}
		m_is_writing_ = false;
	}

private:
	std::mutex m_mutex_;
	volatile int m_read_count_;				// 讀操作持有者計數
	volatile int m_write_count_;			// 寫操作持有者計數
	bool m_is_writing_;						// 是否正在寫
	std::condition_variable m_read_cond_;	// 可讀條件變量
	std::condition_variable m_write_cond;	// 可寫條件變量
};

// 讀鎖
class CReadLock
{
public:
	explicit CReadLock(CRWMutex& rwmutex)
		: m_rwmutex_(rwmutex)
	{
		m_rwmutex_.LockRead();
	}

	virtual ~CReadLock()
	{
		m_rwmutex_.UnLockRead();
	}

private:
	CReadLock() = delete;
	CReadLock(const CReadLock&) = delete;
	CReadLock& operator=(const CReadLock&) = delete;

private:
	CRWMutex& m_rwmutex_;
};

// 寫鎖
class CWriteLock
{
public:
	explicit CWriteLock(CRWMutex& rwmutex)
		: m_rwmutex_(rwmutex)
	{
		m_rwmutex_.LockWrite();
	}

	virtual ~CWriteLock()
	{
		m_rwmutex_.UnLockWrite();
	}

private:
	CWriteLock() = delete;
	CWriteLock(const CWriteLock&) = delete;
	CWriteLock& operator=(const CWriteLock&) = delete;

private:
	CRWMutex& m_rwmutex_;
};


#endif //_RWLOCK_H_

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章