c++中的读写锁

news/2024/10/6 18:28:44

读写锁是一种特殊的锁机制,允许多个线程同时读取共享数据,但在写入共享数据时,只有一个线程可以进行写操作,其他线程必须等待。

这种机制对于读多写少的场景非常有效,可以提高并发性能。以下是通过 shared_lockunique_lockshared_mutexmutex 的解释来说明读写锁的实现和应用。

1. 基本概念

  • 读锁(Shared Lock)

    • 使用 shared_lock 加锁,允许多个线程同时持有读锁,这样它们可以并发地读取共享数据。
    • 在持有读锁的情况下,其他线程仍然可以获取读锁,但无法获取写锁。
  • 写锁(Exclusive Lock)

    • 使用 unique_lock 加锁,只有一个线程可以持有写锁。持有写锁的线程在写入数据时,其他线程无法获取任何类型的锁(无论是读锁还是写锁)。
    • 写锁的目的在于保证数据的安全性和一致性。

2. shared_mutexmutex

  • shared_mutex

    • 是 C++14 引入的一个互斥体类型,专门用于支持读写锁
      -** 它支持共享锁(通过 shared_lock)和独占锁(通过 unique_lock)**。通过这种方式,多个线程可以安全地读取数据,而在写入数据时,可以保证只有一个线程在写。
  • mutex

    • 是最基本的互斥体,提供了互斥访问共享资源的功能。
    • 使用 mutex 时,如果一个线程持有锁,其他线程都无法访问受保护的资源。

3. 示例代码

以下是一个示例,展示了如何使用 shared_mutexshared_lockunique_lock 实现一个简单的读写锁:

#include <iostream>
#include <thread>
#include <shared_mutex>
#include <vector>
#include <chrono>class SharedData {
private:int data;mutable std::shared_mutex mutex;public:SharedData() : data(0) {}// 读操作int read() const {std::shared_lock<std::shared_mutex> lock(mutex); // 共享锁return data;}// 写操作void write(int value) {std::unique_lock<std::shared_mutex> lock(mutex); // 独占锁data = value;}
};// 读线程函数
void reader(SharedData& shared_data, int id) {for (int i = 0; i < 5; ++i) {std::cout << "Reader " << id << " reads: " << shared_data.read() << std::endl;std::this_thread::sleep_for(std::chrono::milliseconds(100));}
}// 写线程函数
void writer(SharedData& shared_data, int value) {for (int i = 0; i < 5; ++i) {shared_data.write(value);std::cout << "Writer writes: " << value << std::endl;std::this_thread::sleep_for(std::chrono::milliseconds(300));value++; // 增加写入值}
}int main() {SharedData shared_data;// 创建读线程std::vector<std::thread> readers;for (int i = 0; i < 3; ++i) {readers.emplace_back(reader, std::ref(shared_data), i);}// 创建写线程std::thread writer_thread(writer, std::ref(shared_data), 0);// 等待线程完成for (auto& r : readers) {r.join();}writer_thread.join();return 0;
}

4. 解释

  • 共享读取

    • read 方法中,使用 shared_lock 来加锁。这允许多个线程同时读取 data,因为它们不会阻塞彼此。
  • 独占写入

    • write 方法中,使用 unique_lock 来加锁。这保证了在写入数据时,其他线程不能读取或写入。
  • 线程安全

    • 通过使用 shared_mutex,确保在读取时允许并发访问,而在写入时则独占访问,有效提高了程序的并发性能。

总结

读写锁是提高读多写少场景下性能的有效机制。通过使用 shared_mutexshared_lockunique_lock,可以实现安全的并发访问,确保数据的一致性和正确性。这种方式在多线程编程中是非常常见的,特别是在需要频繁读取而写入相对较少的应用中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/68397.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

# 2024-2025-1 学号(2024130) 《计算机基础与程序设计》第二周学习总结

作业信息 |这个作业属于哪个课程|<[2024-2025-1-计算机基础与程序设计]> (https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP))| |-- |-- | |这个作业要求在哪里|<[2024-2025-1计算机基础与程序设计第一周作业]>(https://edu.cnblogs.com/campus/besti/2024…

20222412 2024-2025-1 《网络与系统攻防技术》实验一实验报告

1.实验内容 本周学习内容 1.熟悉基本的汇编语言指令及其功能。 2.掌握了栈与堆的概念及其在进程内存管理中的应用以及用户态与内核态的区别。 3.熟练运用了Linux系统下的基本操作命令。 实验任务 1.手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。 2.利用foo函…

序列化器中拿到request

class UpdateMobileSerializer(serializers.ModelSerializer):old = serializers.CharField(write_only=True, validators=[RegexValidator(r"\d{11}", message="格式错误")])mobile = serializers.CharField(write_only=True, validators=[RegexValidator…

面相快速入门教程4五行与面相

4 五行与面相 现在,你进入了旅程中最重要的部分。在这里,你将学习到这些智慧所依据的原则,然后深入了解五种元素或原型的特质,它们在你的脸上闪耀着光芒。五种不同的元素各有两幅肖像样本,每种元素又各有两章。在第一章中,你将探索该性格的总体概况,了解它在你生活中的广…

0923人工智能教育技术学

任务一 (1)水印的功能: 1.版权保护:水印可以用来标识内容的创建者或所有者,从而防止未经授权的复制或分发。 2.身份验证:水印可以用于验证数字内容的真实性和完整性,确保内容在传输过程中没有被篡改。 3.广告和推广:水印可以作为一种低成本的广告手段,增加品牌曝光度。…

『模拟赛』CSP-S模拟9

『模拟赛记录』CSP-S模拟9Rank 烂,知耻而后勇A. 邻面合并 签。 注意到列数 \(m\le 8\),我们可以直接先搜出每一行可能的“分块”情况,然后转移时枚举上一行的所有状态和这一行的所有状态,根据拼接情况来更新答案,最终答案即为 \(n\) 行所有情况的最小值。 赛时开始打的错解…

VC++ 6.0的安装及使用

1. 安装 双击运行程序vc6_cn_full.exe进行安装如果需要更改安装目录,选择浏览进行安装地址的修改,否则点击下一步程序第一次启动会弹出提示框,可去掉“启动时显示提示”选项框,下一次就不会弹出该提示框2. 一个简单的demo初学者建议选择“一个空程序”去创建控制台程序选择…