C++ shared_mutex
C++17把共享锁纳入标准库。允许多个线程以共享方式持有读锁,只允许一个线程持有写锁。
1 #include <stdio.h> 2 #include <thread> 3 #include <shared_mutex> 4 #include <mutex> 5 6 std::shared_mutex mtx; 7 int gi; 8 9 int main() { 10 11 using namespace std::chrono_literals; 12 auto reader = []() { 13 for (int i = 0; i<100; ++i) { 14 mtx.lock_shared(); 15 std::this_thread::sleep_for(500ms); 16 int tmp = gi; 17 mtx.unlock_shared(); 18 printf("reader gi=%d\n", tmp); 19 } 20 }; 21 22 auto writer = []() { 23 for (int i = 0; i<10; ++i) { 24 std::this_thread::sleep_for(5s); 25 mtx.lock(); 26 ++gi; 27 mtx.unlock(); 28 printf("===writer gi=%d\n", gi); 29 } 30 }; 31 32 std::thread a(reader), b(reader), c(writer); 33 34 a.join(); 35 b.join(); 36 c.join(); 37 38 }
第15行,在加持读锁后,即使sleep本线程也不会阻塞其它线程获取读锁(Shared locking)。但是会影响其它线程对写锁(Exclusive locking)的获取。因为写锁要独占方式获得锁,必须等待所有读锁释放。
第24行,如果把sleep放入26行之前,就会阻塞其它线程对写锁和读锁的获取。
标准库还采取RAII方式的,shared_lock管理器:
#include <stdio.h> #include <thread> #include <shared_mutex> #include <mutex> std::shared_mutex mtx; int gi; int main() { using namespace std::chrono_literals; auto reader = []() { for (int i = 0; i<100; ++i) { int tmp = 0; { std::shared_lock<std::shared_mutex> lock(mtx); //等价于 mtx.shared_lock(); std::this_thread::sleep_for(500ms); tmp = gi; } //等价于 mtx.shared_unlock(); printf("reader gi=%d\n", tmp); } }; auto writer = []() { for (int i = 0; i<10; ++i) { std::this_thread::sleep_for(5s); { std::unique_lock<std::shared_mutex> lock(mtx); //等价于mtx.lock(); ++gi; } //等价于 mtx.unlock(); printf("===writer gi=%d\n", gi); } }; std::thread a(reader), b(reader), c(writer); a.join(); b.join(); c.join(); }