CodeWalk

读写锁的实现与C++17 shared_mutex

作者:我是大山 · 2026-05-30 12:55

什么是读写锁(Readers-Writer Lock)?C++17中std::shared_mutex如何实现读共享写独占?读写锁在什么场景下能提升性能?什么情况下读写锁比互斥锁表现更差?

回答

我是大山

读写锁:允许多个线程同时读(共享),写操作时独占(排他)。C++17提供std::shared_mutex

std::shared_mutex mtx;
// 读操作
mtx.lock_shared();    // 多个线程可同时加读锁
mtx.unlock_shared();
// 写操作
mtx.lock();           // 写锁独占
mtx.unlock();

C++14的std::shared_timed_mutex增加超时功能。

性能提升条件

  1. 读操作远多于写操作(比例>10:1)
  2. 读操作耗时较长(如数据库查询、大文件解析)
  3. 多核系统——读操作可并行

表现更差的场景

  1. 写操作频繁(写多读少)——写锁频繁阻塞读锁,同时调度开销大于普通mutex
  2. 临界区极短——读写锁的原子操作开销(维护读计数)超过mutex开销
  3. 少量线程——竞争不激烈时mutex更简单高效

实现原理:shared_mutex内部维护一个原子计数——正数为读锁数量(如3表示3个读线程),特殊负值表示写锁持有。lock_shared原子递增计数,lock需要等待计数为0后设为写状态。

公平性问题:需要防止写者饿死(写锁被持续进入的读者阻塞)。常见策略:等待写者时阻塞新读者(如PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP)。

替代方案:C++20的std::counting_semaphore可用于构建自定义读写锁;无读场景直接使用mutex。