C++ 锁

C++ 锁,第1张

文章目录
  • 互斥锁
    • mutex
    • lock_guard
    • unique_lock
  • 条件锁
    • condition_variable
  • 读写锁
    • C++17 的shared_mutex
    • C++14 的 shared_lock
    • C++ 自己实现读写锁
    • boost的读写锁

互斥锁
说明
std::mutex独占的互斥量,不能递归使用
std::timed_mutex有超时功能的独占互斥量,不能递归使用
std::recursive_mutex递归互斥量,能递归使用
std::recursive_timed_mutex有超时功能的递归互斥量
mutex
#include  

std::mutex mutex_;
mutex_.lock();
mutex_.try_lock();
mutex_.unlock();
lock_guard

建议使用lock_guard替代直接使用mutext.lock()、mutext.unlock(),lock_guard会在构造方法里mutext.lock(),析构方法里mutext.unlock(),主要为了避免中途异常退出导致mutext没有unlock。

#include  

std::mutex mutex_;
{
	std::lock_guard lck(mutex_);
} //出了作用域后自动调用lock_guard的析构方法
unique_lock

lock_guard只能在析构的时候解锁,不提供unlock接口,不够方便,unique_lock提供lock和unlock接口,更灵活

unique_lock比lock_guard灵活很多,效率上差一点,内存占用多一点。

#include  

std::mutex mutex_;
{
	std::unique_lockguard(mutex_);
	guard.unlock();//临时解锁
	guard.lock();//继续上锁
}// 结束时析构guard会临时解锁
条件锁 condition_variable
//使用std::condition_variable等待数据

#include 
#include  

std::mutex mut_;
std::condition_variable con_;

std::queue data_;


void produce(int i)
{
    std::lock_guard lck(mut_);
    data_.push(i);
    con_.notify_one();
}

void consume()
{
    std::lock_guard lck(mut_);   //这里使用unique_lock是为了后面方便解锁
    con_.wait(lck,{[]return !data_.empty();});
    int i=data_.front();
    data_.pop();
}
读写锁 C++17 的shared_mutex
#include  

std::shared_mutex mutex_;

//独占锁
mutex_.lock();
mutex_.try_lock();
mutex_.unlock();

//共享锁
mutex_.lock_shared();
mutex_.try_lock_shared();
mutex_.unlock_shared();
C++14 的 shared_lock
//C++ 14
#include 
 
std::shared_timed_mutex mutex_;
std::shared_lock rlck(mutex_);
std::unique_lock wlck(mutex_
//如下要求在C++17, 因为用到了 shared_mutex
#include  //shared_mutex shared_lock

std::shared_mutex mutex_;
std::shared_lock lck(mutex_);
std::unique_lock lck(mutex_);

C++ 自己实现读写锁
#include 
#include 
#include 
#include 

class readWriteLock {
private:
    std::mutex readMtx;
    std::mutex writeMtx;
    int readCnt; // 已加读锁个数
public:
    readWriteLock() : readCnt(0) {}
    void readLock()
    {
        readMtx.lock();
        if (++readCnt == 1) {
            writeMtx.lock();  // 存在线程读 *** 作时,写加锁(只加一次)
        }
        readMtx.unlock();
    }
    void readUnlock()
    {
        readMtx.lock();
        if (--readCnt == 0) { // 没有线程读 *** 作时,释放写锁
            writeMtx.unlock();
        }
        readMtx.unlock();
    }
    void writeLock()
    {
        writeMtx.lock();
    }
    void writeUnlock()
    {
        writeMtx.unlock();
    }
};

//-------------------------------------------------------------------------------------------------------

volatile int var = 10; // 保持变量 var 对内存可见性,防止编译器过度优化
readWriteLock rwLock; // 定义全局的读写锁变量

void Write() {
    rwLock.writeLock();
    var += 10;
    std::cout << "write var : " << var << std::endl;
    rwLock.writeUnlock();
}

void Read() {
    rwLock.readLock();
    std::cout << "read var : " << var << std::endl;
    rwLock.readUnlock();
}

int main() {
    std::vector writers;
    std::vector readers;
    for (int i = 0; i < 10; i++) {  // 10 个写线程
        writers.push_back(std::thread(Write));  // std::thread t 的写法报错
    }
    for (int i = 0; i < 100; i++) {   // 100 个读线程
        readers.push_back(std::thread(Read));
    }
    for (auto& t : writers) {   // 写线程启动
        t.join();
    }
    for (auto& t : readers) {   // 读线程启动
        t.join();
    }
    std::cin.get();
}
boost的读写锁

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1352517.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-14
下一篇 2022-06-14

发表评论

登录后才能评论

评论列表(0条)

保存