在linux系统中,posix实现了写优先的读写锁,虽然boost也有读写锁,但是不是写优先的,使用Boost的共享锁、条件变量、原子操作实现写优先的读写锁,废话不说了,直接上代码,我测试了,没发现什么问题,欢迎各位大侠指正。

code:

#include <boost/noncopyable.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/interprocess/detail/atomic.hpp>

class CRWLock : public boost::noncopyable
{
public:
 CRWLock()
 {
  m_iWriteCnt = 0;
  m_iWritingCnt = 0;
  m_iReadingCnt = 0;
 }

 ~CRWLock(){}

 int ReadLock()
 {// 先判断是否有等待的写,如果有则不锁
  bool bIncrement = false;
  {
   boost::shared_lock<boost::shared_mutex> rLock(m_sharedMutex);
   if (m_iWriteCnt > 0)
   {// 有线程请求获取写锁,则该线程获取读锁先阻塞等待,让写锁先执行
    m_read_cond.wait(rLock);
    if (m_iReadingCnt == 0)
    {// 没有线程正在读,通知其他线程可以写了
     boost::interprocess::ipcdetail::atomic_inc32(&m_iReadingCnt);
     bIncrement = true;
     m_write_cond.notify_one();
    }
   }
  }
  if (!bIncrement)
  {
   boost::interprocess::ipcdetail::atomic_inc32(&m_iReadingCnt); 
  }  
  return 0;
 }

 int UnReadLock()
 {
  boost::interprocess::ipcdetail::atomic_dec32(&m_iReadingCnt);
  if (m_iReadingCnt == 0)
  {// 没有线程正在读,通知其他线程可以写了
   m_write_cond.notify_one();
  }  
  return 0;
 }

 int WriteLock()
 {
  boost::uint32_t res = boost::interprocess::ipcdetail::atomic_inc32(&m_iWriteCnt); // 写锁自增1
  boost::unique_lock<boost::shared_mutex> wLock(m_sharedMutex);
  res = boost::interprocess::ipcdetail::atomic_inc32(&m_iWritingCnt);
  if(m_iReadingCnt > 0 || m_iWritingCnt > 1)
  {// 有读锁,或者有线程已经获取到写锁了,等待
   m_write_cond.wait(wLock);
  }
  return 0;
 }

 int UnWriteLock()
 {
  boost::interprocess::ipcdetail::atomic_dec32(&m_iWriteCnt);
  boost::interprocess::ipcdetail::atomic_dec32(&m_iWritingCnt);
  if (m_iWritingCnt > 0)
  {// 还有线程要获取写锁权限,已经拿到m_sharedMutex权限了
   m_write_cond.notify_one();
  }
  if (m_iWritingCnt==0)
  {
   m_read_cond.notify_all();
  }
  return 0;
 }

private:
 boost::shared_mutex  m_sharedMutex;            // 共享互斥
 boost::condition_variable_any  m_read_cond;    // 读条件
 boost::condition_variable_any  m_write_cond;   // 写条件

 volatile boost::uint32_t m_iWriteCnt;   // 等待获取写锁权限的计数
 volatile boost::uint32_t m_iWritingCnt; // 正在写的计数

 volatile boost::uint32_t m_iReadingCnt; // 正在读的计数
};

/************************************************************************/
/* 读锁管理类                                                           */
/************************************************************************/
class CReadLockMgr
{
public:
 CReadLockMgr(CRWLock* rwLock)
 {
  m_rwLock = rwLock;
  m_rwLock->ReadLock();
 }

 ~CReadLockMgr()
 {
  m_rwLock->UnReadLock();
 }

private:
 CRWLock* m_rwLock;
};

/************************************************************************/
/* 写锁管理类                                                           */
/************************************************************************/
class CWriteLockMgr
{
public:
 CWriteLockMgr(CRWLock* rwLock)
 {
  m_rwLock = rwLock;
  m_rwLock->WriteLock();
 }

 ~CWriteLockMgr()
 {
  m_rwLock->UnWriteLock();
 }

private:
 CRWLock* m_rwLock;
};

 

Logo

更多推荐