读锁和写锁其实就是通常意义上的共享锁和排他锁。
在 C++14 以前,标准库中是没有共享锁提供的,我们需要使用其他库(如 boost),或自行实现(如利用两个 std::mutex
实现)。C++14 以后标准库中才有了对共享锁 std::shared_timed_mutex
的支持。不过我们更常用的应当是 C++17 中提供的共享锁 std::shared_mutex
。至于两者区别,不是本文重点,读者可以自行了解。本文的建议是除非特别需要,请使用 C++17 中的 std::shared_mutex
。
本文默认读者有一点 C++ 并发编程基础。
我们首先使用 C++17 提供的互斥 std::shared_mutex
,从名字上也能看出来了,这是个共享互斥。
在使用上,读锁(共享锁)使用 std::shared_lock()
操作互斥;建议写锁(排他锁)使用 std::lock_guard()
或 std::unique_lock()
等操作互斥。因为这些包装类提供了 RAII 机制。
我们下面看代码理解:
1 | class TestSharedMutex { |
上面的类中有两个成员函数,read_data()
会读取类成员数据,write_data()
会修改数据。
我们只要在 read_data()
中使用 std::shared_lock
共享地获取并锁住互斥,然后读,
而在 write_data()
中使用 std::lock_guard
排他地获取并锁住互斥,然后写就好了。
当读线程持有的共享锁全部释放之前,写线程获取排他锁时将被阻塞;
反过来一样,在写线程释放排他锁之前,读线程获取共享锁时将被阻塞。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 GuKaifeng's Blog!
评论(延迟加载 / 需要可访问 GitHub Issues)