std::shared_mutex并非万能解药,仅在读多写少且读操作轻量时才具优势;其性能关键在于并发读开销是否低于mutex争用成本,需用std::shared_lock避免异常死锁,并注意windows兼容性及底层实现差异。

std::shared_mutex 不是“读写锁”的万能解药,它只在读多写少、且读操作本身很轻量时才值得用。
std::shared_mutex 和 std::mutex 的性能差异在哪
关键不在“能不能并发读”,而在“并发读的开销是否低于互斥锁的争用成本”。std::shared_mutex 内部维护读计数和写状态,每次 lock_shared() / unlock_shared() 都要原子增减计数;而 std::mutex 在无竞争时只是单次原子操作。实测中,若读操作本身耗时 int),用 std::shared_mutex 反而更慢。
- 读操作越重(如遍历容器、字符串拼接),越可能从共享锁获益
- 写操作越频繁(写占比 >5%),
std::shared_mutex的写饥饿风险越高 - 在 glibc 2.27+(Linux)或较新 libc++ 上,
std::shared_mutex底层才真正使用 futex 或类似机制;旧版本可能退化为内部互斥模拟,完全没优势
std::shared_mutex 的正确用法(别漏掉 shared_lock)
直接调用 lock_shared() / unlock_shared() 容易出错:异常路径下忘记 unlock_shared() 会导致死锁。必须用 RAII 封装 —— 但不是 std::lock_guard,而是 std::shared_lock。
std::shared_mutex rwmtx;
std::vector<int> data;
<p>// ✅ 正确:自动管理生命周期
void read_data() {
std::shared_lock<std::shared_mutex> lock(rwmtx);
for (int x : data) { /<em> ... </em>/ }
}</p><p>// ❌ 危险:异常时 unlock_shared 不会被调用
void bad_read() {
rwmtx.lock_shared();
do_something_that_might_throw();
rwmtx.unlock_shared(); // 这行可能永远不执行
}Windows 上的兼容性陷阱(_WIN32 + MSVC)
MSVC 19.20(VS 2019 16.0)之前,std::shared_mutex 是空实现(仅声明,链接失败);即使新版,其 Windows 实现基于 Slim Reader/Writer Locks,但默认启用“公平模式”,会显著拖慢读吞吐。需手动关闭:
立即学习“C++免费学习笔记(深入)”;
- 编译时定义
_ENABLE_ATOMIC_ALIGNMENT_FIX(部分旧版需要) - 更关键的是:避免在高并发读场景下混用
std::shared_mutex和 Windows API 的AcquireSRWLockShared—— 它们不兼容 - Clang-cl 或 MinGW-w64 用户注意:
libstdc++和libc++对std::shared_mutex的 Windows 支持程度不同,建议统一用libc++并确认版本 ≥12
真正难的不是怎么写那几行代码,而是判断当前数据访问模式是否真的适合共享锁 —— 很多时候加个 std::atomic<bool></bool> 做读缓存标记,比换锁更简单有效。










