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();

}

 

posted @ 2018-03-26 14:47  thomas76  阅读(1042)  评论(0编辑  收藏  举报