一、是什么
读写锁是一种读写机制,用于控制对共享资源的访问,允许多个线程同时读取资源,写入资源时只允许一个线程独占访问。
二、特征
读操作不会破坏数据完整性,可以共行,写操作可能会破坏数据完整性,必须互斥,读写之间也要互斥。适用于读多写少的场景。
读写锁分为共享锁和独占锁:
1.共享锁
①允许多个线程同时持有
②多个线程可以并发地读取共享资源
③不能与独占锁同时持有
2.独占锁
①只允许一个线程持有
②持有锁的线程可以写入共享资源
③多个线程拿到共享锁之后,在同一时间,只允许一个线程拿到独占锁,并且其他线程不能再持有共享锁或独占锁
④独占锁一般为unique_lock
三、shared_mutex
c++17标准。多读单写的并发访问模式。
shared_mutex可以执行独占锁,也可以执行共享锁
排他性锁定:lock 、try_lock、unlock
共享锁定:lock_shared、try_lock_shared、unlock_shared
在实现独占锁时,通常使用unique_lock,而不是shared_mutex。
四、shared_lock
c++17标准。用于管理std::shared_mutex的共享锁,能自动获取和释放共享锁。
shared_lock和unique_lock配合对shared_mutex锁进行管理,实现读写锁。
#include <shared_mutex>
#include <thread>
#include <iostream>
#include <vector>
std::shared_mutex rw_mutex; //读写锁
int shared_data = 0;
void reader()
{
std::shared_lock lock(rw_mutex);
std::cout << "Reader thread:" << std::this_thread::get_id() << " reads data:" << shared_data << std::endl;
}
void writer(int value)
{
std::unique_lock lock(rw_mutex);
shared_data = value;
std::cout << "Writer thread:" << std::this_thread::get_id() << " writes data:" << shared_data << std::endl;
}
int main()
{
std::vector<std::thread>threads;
for (int i = 0; i < 5; ++i)
{
threads.emplace_back(reader);
}
for (int i = 0; i < 2; ++i)
{
threads.emplace_back(writer,i);
}
for (std::thread& t: threads)
{
t.join();
}
return 0;
}
会发现读线程的打印是乱的,写线程是规整的,因为读读不互斥,写是互斥的。