C++ std::shared_mutex读写锁

0.前言

读写锁把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作。C++17开始,标准库提供了shared_mutex类(在这之前,可以使用boost的shared_mutex类或系统相关api)。和其他便于独占访问的互斥类型不同,shared_mutex 拥有两个访问级别:

  • 共享:多个线程能共享同一互斥的所有权(如配合shared_lock);
  • 独占:仅有一个线程能占有互斥(如配合lock_guard、unique_lock)。

shared_mutex 通常用于多个读线程能同时访问同一资源而不导致数据竞争,但只有一个写线程能访问的情形。

1.认识std::shared_mutex

通过查看该类的接口(https://zh.cppreference.com/w/cpp/thread/shared_mutex),可以看到,该类除了互斥锁定接口,还提供了共享锁定接口。

  • lock() 锁定互斥。若另一线程已锁定互斥,则到 lock() 的调用将阻塞执行,直至获得锁。可以用 std::lock_guard 和 std::unique_lock 管理互斥锁定。
  • shared_lock() 获得互斥的共享所有权。若另一线程以排他性所有权保有互斥,则到 shared_lock() 的调用将阻塞执行,直到能取得共享所有权。若已以任何模式(排他性或共享)占有 mutex 的线程调用 shared_lock() ,则行为未定义。若多于实现定义最大数量的共享所有者已以共享模式锁定互斥,则 shared_lock() 阻塞执行,直至共享所有者的数量减少。所有者的最大数量保证至少为 10000 。可以用std::shared_lock管理共享锁定。

2.实例演示

这里直接借用在线手册上的例子:

#include <iostream>
//std::unique_lock
#include <mutex> 
#include <shared_mutex>
#include <thread>

class ThreadSafeCounter {
public:
	ThreadSafeCounter() = default;

	// 多个线程/读者能同时读计数器的值。
	unsigned int get() const {
		std::shared_lock<std::shared_mutex> lock(mutex_);
		return value_;
	}

	// 只有一个线程/写者能增加/写线程的值。
	void increment() {
		std::unique_lock<std::shared_mutex> lock(mutex_);
		value_++;
	}

	// 只有一个线程/写者能重置/写线程的值。
	void reset() {
		std::unique_lock<std::shared_mutex> lock(mutex_);
		value_ = 0;
	}

private:
	mutable std::shared_mutex mutex_;
	unsigned int value_ = 0;
};

int main() {
	ThreadSafeCounter counter;

	auto increment_and_print = [&counter]() {
		for (int i = 0; i < 3; i++) {
			counter.increment();
			std::cout << std::this_thread::get_id() << '\t' << counter.get() << std::endl;
		}
	};

	std::thread thread1(increment_and_print);
	std::thread thread2(increment_and_print);

	thread1.join();
	thread2.join();

	system("pause");
	return 0;
}

(本文主要是学习参考手册上的内容。)

  • 7
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

龚建波

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

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

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

打赏作者

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

抵扣说明:

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

余额充值