C++中的std::shared_mutex怎么实现读写锁

来源:前端技术作者:阿亮头衔:草根站长
导读:本期聚焦于小伙伴创作的《C++中的std::shared_mutex怎么实现读写锁》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++中的std::shared_mutex怎么实现读写锁》有用,将其分享出去将是对创作者最好的鼓励。

在C++17及之后的标准库中,std::shared_mutex是专门用于实现读写锁的同步原语,它支持两种锁模式:共享锁和独占锁,能够很好地满足多读单写的并发控制需求,多个线程可以同时获取共享锁进行读操作,而写操作需要获取独占锁,此时会阻塞所有其他的读和写请求。

C++中的std::shared_mutex怎么实现读写锁

std::shared_mutex的核心特性

std::shared_mutex和普通的std::mutex不同,它区分了读操作和写操作的锁权限:

  • 共享锁:通过lock_shared()方法获取,多个线程可以同时持有共享锁,适合读操作场景,不会互相阻塞。
  • 独占锁:通过lock()方法获取,同一时间只能有一个线程持有独占锁,适合写操作场景,会阻塞所有尝试获取共享锁或独占锁的其他线程。
  • 对应的解锁方法分别为unlock_shared()unlock(),也可以配合标准锁管理器自动管理锁的生命周期。

配合锁管理器简化使用

手动调用lock和unlock方法容易出现遗漏解锁的问题,实际开发中通常会配合std::shared_lockstd::unique_lock来自动管理锁:

  • std::shared_lock:用于管理共享锁,构造时自动获取共享锁,析构时自动释放,适合包装读操作逻辑。
  • std::unique_lock:用于管理独占锁,构造时自动获取独占锁,析构时自动释放,适合包装写操作逻辑。

完整实现示例

下面是一个简单的计数器类,使用std::shared_mutex实现多读单写的并发控制,多个线程可以同时读取计数器的值,而修改计数器值的操作会独占执行:

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

class ReadWriteCounter {
private:
    mutable std::shared_mutex mtx; //  mutable允许在const成员函数中修改
    int counter = 0;

public:
    // 读操作:获取共享锁,多个线程可同时调用
    int get_counter() const {
        std::shared_lock<std::shared_mutex> lock(mtx); // 自动获取共享锁
        return counter;
    }

    // 写操作:获取独占锁,同一时间只能有一个线程调用
    void increment() {
        std::unique_lock<std::shared_mutex> lock(mtx); // 自动获取独占锁
        ++counter;
    }
};

// 读线程函数
void read_task(const ReadWriteCounter& counter, int thread_id) {
    for (int i = 0; i < 3; ++i) {
        int val = counter.get_counter();
        std::cout << "读线程" << thread_id << " 读取到值: " << val << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
}

// 写线程函数
void write_task(ReadWriteCounter& counter, int thread_id) {
    for (int i = 0; i < 2; ++i) {
        counter.increment();
        std::cout << "写线程" << thread_id << " 完成一次自增" << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
    }
}

int main() {
    ReadWriteCounter counter;
    std::vector<std::thread> threads;

    // 创建3个读线程
    for (int i = 0; i < 3; ++i) {
        threads.emplace_back(read_task, std::ref(counter), i + 1);
    }

    // 创建2个写线程
    for (int i = 0; i < 2; ++i) {
        threads.emplace_back(write_task, std::ref(counter), i + 1);
    }

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

    std::cout << "最终计数器值: " << counter.get_counter() << std::endl;
    return 0;
}

使用注意事项

  • std::shared_mutex是C++17引入的,如果使用更早的标准版本,需要自行实现读写锁逻辑或者使用第三方库。
  • 共享锁和独占锁的优先级问题:标准没有规定锁的获取优先级,不同编译器的实现可能有差异,不要依赖特定的优先级行为。
  • 避免重复获取锁:同一个线程不要同时尝试获取共享锁和独占锁,也不要重复获取同一种锁,否则可能导致死锁。
  • 如果读操作远多于写操作,使用std::shared_mutex能显著提升并发性能,若写操作很频繁,其性能可能和普通互斥锁接近甚至更差。

std::shared_mutex读写锁多读单写并发控制C++修改时间:2026-07-11 15:42:33

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。