通知图标

欢迎访问津桥芝士站

mutex:std::shared_mutex::lock

来自AI助手的总结
C++17引入的`std::shared_mutex`支持多线程并行读写,提升读操作效率,适用于读多写少的场景。

引入

C++17 标准通过 <mutex> 头文件引入了许多新的功能,以支持多线程编程。在众多新特性中,std::shared_mutex 是一种特殊的互斥量,设计用于支持读写操作的并行性。与传统的互斥量不同,std::shared_mutex 允许多个线程同时读取共享资源,但在写入时则要求独占锁定。std::shared_mutex::lock 方法用于申请写锁,确保只有一个线程能够访问写临界区,从而对共享数据进行修改。学习并理解这一功能,对于设计高性能的多线程程序至关重要。

1. 特性与函数介绍

1.1 特性

  • 共享与独占std::shared_mutex 允许多个线程并发地获取共享锁来读取数据,而独占锁则允许只有一个线程修改数据,简化了读多写少的场景。
  • 锁粒度控制:通过写锁与读锁的分开控制,使得程序在高并发情况下能够提高读取性能。
  • 适用场景广泛:对于场景中有大量读取操作而较少写入的应用,std::shared_mutex 能显著提升效率。

1.2 函数语法

std::shared_mutex::lock 的基本语法如下:

#include <mutex>

class shared_mutex : public mutex {
public:
    void lock(); // 获取独占锁
    ...
};
  • 无参数:该函数调用时不需要传递参数。
  • 无返回值:成功获取锁后不会返回任何值。

2. 完整示例代码

以下示例展示了如何使用 std::shared_mutex::lock 在多线程环境中安全地进行写操作。

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

std::shared_mutex smtx;           // 定义共享互斥锁
std::vector<int> sharedVector;    // 共享数据

// 写操作函数
void writeData(int value) {
    smtx.lock(); // 申请独占锁
    sharedVector.push_back(value); 
    std::cout << "Thread " << std::this_thread::get_id() 
              << " wrote value: " << value << std::endl;
    smtx.unlock(); // 释放锁
}

// 读操作函数
void readData() {
    smtx.lock_shared(); // 申请共享锁
    std::cout << "Thread " << std::this_thread::get_id() 
              << " read values: ";
    for (const auto& val : sharedVector) {
        std::cout << val << " ";
    }
    std::cout << std::endl;
    smtx.unlock_shared(); // 释放共享锁
}

int main() {
    const int numWriteThreads = 3; // 写线程数量
    const int numReadThreads = 2;   // 读线程数量
    std::thread writers[numWriteThreads];
    std::thread readers[numReadThreads];

    // 启动写线程
    for (int i = 0; i < numWriteThreads; ++i) {
        writers[i] = std::thread(writeData, i+1);
    }

    // 启动读线程
    for (int i = 0; i < numReadThreads; ++i) {
        readers[i] = std::thread(readData);
    }

    // 等待所有线程完成
    for (auto& writer : writers) {
        writer.join();
    }
    for (auto& reader : readers) {
        reader.join();
    }

    return 0;
}

3. 代码解析

  1. 引入必要的头文件

    • 包含 <mutex><thread> 和 <shared_mutex>,以及标准输入输出库。
  2. 定义共享数据和互斥锁

    • 创建一个 std::shared_mutex smtx 用于访问共享数据,定义一个共享的整型向量 std::vector<int> sharedVector 用于线程间的数据共享。
  3. 定义写操作函数

    • 在 writeData 函数中,首先请求独占锁,调用 smtx.lock(),确保唯一访问共享资源,然后向向量中添加数据,并在完成后释放锁(smtx.unlock())。
  4. 定义读操作函数

    • 在 readData 函数中,申请共享锁 (smtx.lock_shared()),允许多个线程同时读取共享数据,随后展示向量中的所有内容。最后,释放共享锁 (smtx.unlock_shared())。
  5. 主函数中的线程管理

    • 在 main 函数中,创建多条线程分别进行写入和读取的操作,并使用 join() 等待其完成。

4. 适用场景分析

4.1 读多写少的场景

在需要频繁读取但较少写操作的场景中,std::shared_mutex 尤其有效,可以提高系统在处理读取数据时的性能。

4.2 日志系统或统计管理

在实现日志记录或状态监控的系统中,多个线程可能需要同时读取日志,但写操作相对较少,因此使用共享互斥锁十分合适。

4.3 共享数据库连接

在数据库连接池应用中,多个线程可同时读取连接信息,写操作放在连接创建或释放时,能有效避免资源浪费。

5. 总结

std::shared_mutex::lock 是 C++ 提供的一种重要互斥机制,旨在提高并发程序中读操作的效率。通过允许多个线程共享访问同时对修改操作的独占性质, std::shared_mutex 提供了一种高效的方法来管理共享数据的处理。合理使用这一机制,不仅能够降低由于资源争用导致的性能瓶颈,还能保证数据的一致性与稳定性。掌握这一特性帮助开发者在多线程编程时精确控制资源访问,在性能与安全之间实现良好的平衡。

请登录后发表评论

    没有回复内容

正在唤醒异次元光景……