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 <mutex>
#include <condition_variable>

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);
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林多

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值