在C++17及之后的标准库中,std::shared_mutex是专门用于实现读写锁的同步原语,它支持两种锁模式:共享锁和独占锁,能够很好地满足多读单写的并发控制需求,多个线程可以同时获取共享锁进行读操作,而写操作需要获取独占锁,此时会阻塞所有其他的读和写请求。

std::shared_mutex的核心特性
std::shared_mutex和普通的std::mutex不同,它区分了读操作和写操作的锁权限:
- 共享锁:通过
lock_shared()方法获取,多个线程可以同时持有共享锁,适合读操作场景,不会互相阻塞。 - 独占锁:通过
lock()方法获取,同一时间只能有一个线程持有独占锁,适合写操作场景,会阻塞所有尝试获取共享锁或独占锁的其他线程。 - 对应的解锁方法分别为
unlock_shared()和unlock(),也可以配合标准锁管理器自动管理锁的生命周期。
配合锁管理器简化使用
手动调用lock和unlock方法容易出现遗漏解锁的问题,实际开发中通常会配合std::shared_lock和std::unique_lock来自动管理锁:
std::shared_lock:用于管理共享锁,构造时自动获取共享锁,析构时自动释放,适合包装读操作逻辑。std::unique_lock:用于管理独占锁,构造时自动获取独占锁,析构时自动释放,适合包装写操作逻辑。
完整实现示例
下面是一个简单的计数器类,使用std::shared_mutex实现多读单写的并发控制,多个线程可以同时读取计数器的值,而修改计数器值的操作会独占执行:
#include <iostream>
#include <thread>
#include <vector>
#include <shared_mutex>
class ReadWriteCounter {
private:
mutable std::shared_mutex mtx; // mutable允许在const成员函数中修改
int counter = 0;
public:
// 读操作:获取共享锁,多个线程可同时调用
int get_counter() const {
std::shared_lock<std::shared_mutex> lock(mtx); // 自动获取共享锁
return counter;
}
// 写操作:获取独占锁,同一时间只能有一个线程调用
void increment() {
std::unique_lock<std::shared_mutex> lock(mtx); // 自动获取独占锁
++counter;
}
};
// 读线程函数
void read_task(const ReadWriteCounter& counter, int thread_id) {
for (int i = 0; i < 3; ++i) {
int val = counter.get_counter();
std::cout << "读线程" << thread_id << " 读取到值: " << val << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
// 写线程函数
void write_task(ReadWriteCounter& counter, int thread_id) {
for (int i = 0; i < 2; ++i) {
counter.increment();
std::cout << "写线程" << thread_id << " 完成一次自增" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
}
int main() {
ReadWriteCounter counter;
std::vector<std::thread> threads;
// 创建3个读线程
for (int i = 0; i < 3; ++i) {
threads.emplace_back(read_task, std::ref(counter), i + 1);
}
// 创建2个写线程
for (int i = 0; i < 2; ++i) {
threads.emplace_back(write_task, std::ref(counter), i + 1);
}
// 等待所有线程执行完成
for (auto& t : threads) {
t.join();
}
std::cout << "最终计数器值: " << counter.get_counter() << std::endl;
return 0;
}
使用注意事项
- std::shared_mutex是C++17引入的,如果使用更早的标准版本,需要自行实现读写锁逻辑或者使用第三方库。
- 共享锁和独占锁的优先级问题:标准没有规定锁的获取优先级,不同编译器的实现可能有差异,不要依赖特定的优先级行为。
- 避免重复获取锁:同一个线程不要同时尝试获取共享锁和独占锁,也不要重复获取同一种锁,否则可能导致死锁。
- 如果读操作远多于写操作,使用std::shared_mutex能显著提升并发性能,若写操作很频繁,其性能可能和普通互斥锁接近甚至更差。
std::shared_mutex读写锁多读单写并发控制C++修改时间:2026-07-11 15:42:33