C++ 读写锁
读写锁(Read-Write Lock)是一种同步原语,用于解决多线程环境下对共享资源的并发访问问题。它允许多个读线程同时访问共享资源,但在写线程访问资源时,其他读写线程将被阻塞。读写锁的主要目的是提高读多写少场景下的并发性能。
以下是关于读写锁的一些关键点:
读写锁有两种类型的锁:读锁(shared lock)和写锁(unique lock)。
- 读锁:允许多个线程同时持有读锁,这意味着多个读线程可以同时访问共享资源。在获取读锁期间,写线程将被阻塞,直到所有读线程释放读锁。
- 写锁:只允许一个线程持有写锁,以独占方式访问共享资源。在获取写锁期间,其他读写线程都将被阻塞,直到写线程释放写锁。
- 在C++11中,读写锁由std::shared_mutex实现。要使用读写锁,需要使用std::shared_lock来获取共享读锁,使用std::unique_lock来获取独占写锁。
- 使用读写锁可以减小锁的竞争,提高多线程程序的性能。然而,当写操作较多时,读写锁的优势会减弱,因为它会导致大量线程等待。
- 读写锁适用于读操作远多于写操作的场景。在这种场景下,读写锁可以显著提高程序的性能,因为多个读线程可以同时访问共享资源,而不会因为锁竞争而导致性能下降。在写操作较多的场景中,读写锁的优势较小。
总之,读写锁是一种在多线程环境下保护共享资源的有效方法,特别适用于读多写少的场景。通过允许多个读线程并发访问共享资源,读写锁可以显著提高程序性能。然而,在写操作较多的情况下,其优势会相对减弱。在实际应用中,选择合适的锁类型可以帮助您实现更高效的多线程程序。
示例
#include <iostream>
#include <mutex>
#include <shared_mutex>
#include <thread>
#include <vector>
std::shared_mutex sm;
int shared_data = 0;
void reader() {
for (int i = 0; i < 5; ++i) {
std::shared_lock<std::shared_mutex> lock(sm);
std::cout << "Reader thread " << std::this_thread::get_id() << " reads " << shared_data << std::endl;
lock.unlock();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
void writer() {
for (int i = 0; i < 5; ++i) {
std::unique_lock<std::shared_mutex> lock(sm);
++shared_data;
std::cout << "Writer thread " << std::this_thread::get_id() << " writes " << shared_data << std::endl;
lock.unlock();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
int main() {
std::vector<std::thread> threads;
for (int i = 0; i < 3; ++i) {
threads.push_back(std::thread(reader));
}
threads.push_back(std::thread(writer));
for (auto& t : threads) {
t.join();
}
return 0;
}