C++实现读写锁

本文介绍了如何在C++17中使用std::shared_mutex实现读写锁,区分了std::shared_lock和std::unique_lock的作用,并通过示例展示了如何在多线程环境中管理和同步共享数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++ 17实现读写锁

在C++中,实现读写锁可以使用std::shared_mutex,它是C++17标准中引入的。读写锁允许多个线程同时读取一个共享资源,但在写入时,只允许一个线程对资源进行写入,并阻止其他线程读取或写入。

下面是使用std::shared_mutex实现读写锁的示例代码,包括一个简单的共享数据访问类和在main函数中的测试:

#include <iostream>
#include <shared_mutex>
#include <string>
#include <thread>
#include <vector>
#include <mutex>

class SharedData {
private:
    int data;
    mutable std::shared_mutex mutex;

public:
    SharedData(int initial_data) : data(initial_data) {}    
    
    // 读取数据的函数
    int readData() const {
        std::shared_lock<std::shared_mutex> lock(mutex);
        // 假设读取数据需要一些时间
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        return data;
    }

    // 写入数据的函数
    void writeData(int new_data) {
        std::unique_lock<std::shared_mutex> lock(mutex);
        // 假设写入数据需要一些时间
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        data = new_data;
    }
};

int main() {
    SharedData sharedData(0);

    // 创建多个线程进行读写操作
    std::vector<std::thread> threads;

    // 启动一些读取线程
    for (int i = 0; i < 5; ++i) {
        threads.push_back(std::thread([&sharedData, i]() {
            std::cout << "Thread " << i << " read data: " << sharedData.readData() << std::endl;
        }));
    }

    // 启动一些写入线程
    for (int i = 0; i < 2; ++i) {
        threads.push_back(std::thread([&sharedData, i]() {
            sharedData.writeData(i * 10);
            std::cout << "Thread " << i + 5 << " wrote data: " << i * 10 << std::endl;
        }));
    }

    // 等待所有线程完成
    for (auto& thread : threads) {
        thread.join();
    }

    return 0;
}

在这个示例中:

  • SharedData 类中使用 std::shared_mutex 来实现读写锁。
  • readData 方法使用 std::shared_lock 来获取共享锁,允许多个线程同时读取数据。
  • writeData 方法使用 std::unique_lock 来获取独占锁,只允许一个线程写入数据。
  • main 函数中创建了多个线程,模拟并发读写场景。

编译这段代码需要支持C++17的编译器,使用如下编译指令:

g++ -std=c++17 your_file_name.cpp -o your_program -lpthread

替换 your_file_name.cppyour_program 为你的文件名和希望生成的程序名。这段代码在一个多线程环境下测试了读写锁的工作方式。

mutable关键字有什么作用

在C++中,mutable 关键字用于声明一个类成员变量,表示即使在一个 const 成员函数内部,该变量也可以被修改。通常情况下,const 成员函数中不允许修改任何成员变量,因为这样的函数承诺不会修改对象的状态。

在上面的代码中,mutable 关键字用于 std::shared_mutex 类型的 mutex 成员变量:

mutable std::shared_mutex mutex;

这样使用的原因是即使在 const 成员函数中,也需要能够对 mutex 进行锁定和解锁操作。锁定和解锁操作会修改 mutex 的内部状态,但这种修改并不违背 const 函数的语义,即不会改变对象的公共状态或逻辑状态。

具体来说,在 readData 函数中:

int readData() const {
    std::shared_lock<std::shared_mutex> lock(mutex);
    ...
}

尽管 readData 被声明为 const,表示它不会修改 SharedData 对象的逻辑状态,我们仍然需要对 mutex 进行操作以确保线程安全。使用 mutable 关键字可以实现这一点,它使得即使在 const 方法中,也可以对 mutex 进行加锁和解锁操作,而不违反 const 方法的约定。这允许在保持数据成员不变的情况下进行同步操作,是多线程编程中一种常见的模式。

std::shared_lock和std::unique_lock的区别

std::shared_lock 和 std::unique_lock 是 C++ 标准库中的两种锁管理器,它们都用于管理某种互斥量(mutex)的锁定状态,但是用途和特性有所不同。

std::unique_lock
std::unique_lock 是一个通用的互斥锁管理器,它可以用于任何互斥量。
它提供了对互斥量的独占控制,即在同一时间内只有一个 std::unique_lock 可以持有互斥量。
它比 std::lock_guard 更灵活,允许延迟锁定、尝试锁定、时间锁定以及手动锁定和解锁。
通常用于需要细粒度控制互斥量的场景。
std::shared_lock
std::shared_lock 是用于管理共享互斥量(例如 std::shared_mutex)的锁管理器。
它提供了对互斥量的共享控制,允许多个 std::shared_lock 同时持有互斥量,但在任何 std::unique_lock 持有互斥量时,无法获取。
主要用于实现读写锁模式,其中读操作可以并发执行,但写操作必须独占访问。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

令狐掌门

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

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

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

打赏作者

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

抵扣说明:

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

余额充值