std::shared_mutex 举例

std::shared_mutex 是 C++17 引入的一个类型,它允许多个线程同时获取共享锁(shared lock),但只允许一个线程独占锁(exclusive lock)。这样,多个线程可以并发地读取共享数据,但在写入数据时,只有一个线程能够独占访问,以保证数据的一致性。

下面是一个使用 std::shared_mutex 的例子:

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

class SharedCounter {
public:
    SharedCounter() : count(0) {}

    // 读取计数器的值
    int get_count() const {
        std::shared_lock<std::shared_mutex> lock(mutex_); // 获取共享锁
        return count;
    }

    // 增加计数器的值
    void increment() {
        std::unique_lock<std::shared_mutex> lock(mutex_); // 获取独占锁
        ++count;
        std::cout << "Counter incremented to " << count << " by thread " << std::this_thread::get_id() << std::endl;
    }

    // 重置计数器的值
    void reset() {
        std::unique_lock<std::shared_mutex> lock(mutex_); // 获取独占锁
        count = 0;
        std::cout << "Counter reset to 0 by thread " << std::this_thread::get_id() << std::endl;
    }

private:
    mutable std::shared_mutex mutex_; // 使用可变的共享互斥量
    int count;
};

// 线程函数,用于增加计数器的值
void increment_counter(SharedCounter& counter, int num_increments) {
    for (int i = 0; i < num_increments; ++i) {
        counter.increment();
        std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 暂停一段时间,模拟实际工作
    }
}

int main() {
    SharedCounter counter;

    // 创建多个线程来增加计数器的值
    std::vector<std::thread> threads;
    for (int i = 0; i < 5; ++i) {
        threads.emplace_back(increment_counter, std::ref(counter), 10);
    }

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

    // 输出最终计数器的值
    std::cout << "Final counter value: " << counter.get_count() << std::endl;

    // 重置计数器的值
    counter.reset();

    return 0;
}

在这个例子中,SharedCounter 类有一个 std::shared_mutex 类型的成员 mutex_,用来保护 count 成员变量。increment 和 reset 成员函数使用 std::unique_lock 来获取独占锁,确保在修改 count 时没有其他线程可以访问它。而 get_count 成员函数使用 std::shared_lock 来获取共享锁,允许多个线程同时读取 count 的值。

注意,increment 和 reset 成员函数使用独占锁,是因为这些操作会修改 count 的值,需要保证原子性和数据一致性。而 get_count 成员函数使用共享锁,是因为它只读取 count 的值,不会修改它,因此允许多个线程并发读取。

这个例子展示了 std::shared_mutex 的基本用法,你可以根据实际需求调整线程的数量、操作次数等。同时,请确保理解共享锁和独占锁之间的区别,以及它们如何影响资源的并发访问。

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个使用 std::shared_mutex 实现读写分离的示例: ```cpp #include <iostream> #include <thread> #include <mutex> #include <shared_mutex> #include <chrono> std::shared_mutex g_mutex; // 全局共享互斥锁 int g_data = 0; // 全局共享数据 void reader(int id) { while (true) { std::shared_lock<std::shared_mutex> lock(g_mutex); // 获取读锁 std::cout << "Reader " << id << " read data: " << g_data << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(500)); // 模拟读取数据的过程 } } void writer(int id) { while (true) { std::unique_lock<std::shared_mutex> lock(g_mutex); // 获取写锁 ++g_data; // 修改共享数据 std::cout << "Writer " << id << " wrote data: " << g_data << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // 模拟写入数据的过程 } } int main() { std::thread t1(reader, 1); std::thread t2(reader, 2); std::thread t3(writer, 1); std::thread t4(writer, 2); t1.join(); t2.join(); t3.join(); t4.join(); return 0; } ``` 在上面的示例中,我们定义了一个全局共享互斥锁 `g_mutex` 和一个全局共享数据 `g_data`。读线程通过获取共享互斥锁的读锁来读取共享数据,写线程则通过获取共享互斥锁的写锁来修改共享数据。在写线程修改共享数据时,读线程会等待写操作完成后才能继续读取共享数据。通过使用 std::shared_mutex 实现读写分离的互斥访问,可以提高读取共享数据的并发度,从而提高程序的性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值