c++读写锁实现

c++读写锁实现

  • C++17,提供了shared_mutex。配合C++14,提供的shared_lock。及C++11,提供的 unique_lock, 可以方便实现读写锁。
  • 但上述的前提是,允许你使用C++17。在国内的开发环境下,别说C++17,连C++11用的也不多。
  • 所以,大多数时候,我们需要自己实现一套C++读写锁(C++11环境下)。

代码实现

  • RWLock.h
#ifndef RWLOCK__H
#define RWLOCK__H

#ifndef __cplusplus
#    error ERROR: This file requires C++ compilation(use a .cpp suffix)
#endif

#include 
#include 

namespace linduo {

class RWLock {
 public:
    RWLock();
    virtual ~RWLock() = default;

    void lockWrite();
    void unlockWrite();
    void lockRead();
    void unlockRead();

 private:
    volatile int m_readCount;
    volatile int m_writeCount;
    volatile bool m_isWriting;
    std::mutex m_Lock;
    std::condition_variable m_readCond;
    std::condition_variable m_writeCond;
};

class ReadGuard {
 public:
    explicit ReadGuard(RWLock& lock);
    virtual ~ReadGuard();

 private:
    ReadGuard(const ReadGuard&);
    ReadGuard& operator=(const ReadGuard&);

 private:
    RWLock &m_lock;
};


class WriteGuard {
 public:
    explicit WriteGuard(RWLock& lock);
    virtual ~WriteGuard();

 private:
    WriteGuard(const WriteGuard&);
    WriteGuard& operator=(const WriteGuard&);

 private:
  RWLock& m_lock;
};

} /* namespace linduo */
#endif  // RWLOCK__H
  • RWLock.cpp
#include "RWLock.h"

namespace linduo {

RWLock::RWLock()
    : m_readCount(0)
    , m_writeCount(0)
    , m_isWriting(false) {
    }

void RWLock::lockRead() {
    std::unique_lock<std::mutex> gurad(m_Lock);
    m_readCond.wait(gurad, [=] { return 0 == m_writeCount; });
    ++m_readCount;
}

void RWLock::unlockRead() {
    std::unique_lock<std::mutex> gurad(m_Lock);
    if (0 == (--m_readCount)
        && m_writeCount > 0) {
        // One write can go on
        m_writeCond.notify_one();
    }
}

void RWLock::lockWrite() {
    std::unique_lock<std::mutex> gurad(m_Lock);
    ++m_writeCount;
    m_writeCond.wait(gurad, [=] { return (0 == m_readCount) && !m_isWriting; });
    m_isWriting = true;
}

void RWLock::unlockWrite() {
    std::unique_lock<std::mutex> gurad(m_Lock);
    m_isWriting = false;
    if (0 == (--m_writeCount)) {
        // All read can go on
        m_readCond.notify_all();
    } else {
        // One write can go on
        m_writeCond.notify_one();
    }
}

ReadGuard::ReadGuard(RWLock &lock)
    : m_lock(lock) {
    m_lock.lockRead();
}

ReadGuard::~ReadGuard() {
    m_lock.unlockRead();
}

WriteGuard::WriteGuard(RWLock &lock)
    : m_lock(lock) {
    m_lock.lockWrite();
}

WriteGuard::~WriteGuard() {
    m_lock.unlockWrite();
}

} /* namespace linduo */
  • 使用
RWLock m_Lock;

void func() {
   // 写锁
   WriteGuard autoSync(m_Lock);
}

void func() {
  // 读锁
  ReadGuard autoSync(m_Lock);
}

你可能感兴趣的:(C++)