irpas技术客

c++ 并发-读写锁(shared_mutex,shared_lock)_京日暮里_c++ 读写锁

网络 5242

目录

1.前言

2.正文

3.代码和验证

1.前言:

前几日上班时,因为底层逻辑修改。多线程情况下,许多函数如果依然按照原有的锁去串行执行,效率会很低。(原先是 std::mutex ,以及每个函数用的锁是std::lock_guard)

这时我的领导给我新任务,修改多线程的锁,在修改后,要求函数 1 函数2 要能并发执行,且前两者并发执行时与函数 3 函数4 函数5是互斥的。而函数 3,4,5与所有函数都互斥。(例如函数3运行的时候,函数1 2 4 5都是卡着等待函数3执行完毕再继续执行)。

我实在是不会做,这个时候请教我领导,他告诉我用读写锁就能解决问题。c++读写锁的应用也就是使用 shared_mutex,shared_lock,这两者者解决问题。

这是本人对此次经历的记录,可能写的并不太好。可以参考他人文章和cppRefrecne官方文章。

C++多线程——读写锁shared_lock/shared_mutex_princeteng的博客-CSDN博客_shared_lock

std::shared_lock - cppreference.com

2.正文:关于shared_mutex,shared_lock的知识和描述

shared_mutex?类是一个同步原语,可用于保护共享数据不被多个线程同时访问。与便于独占访问的其他互斥类型不同,shared_mutex 拥有二个访问级别:

共享?- 多个线程能共享同一互斥的所有权。 独占性?- 仅一个线程能占有互斥。

若一个线程已获取独占性锁(通过?lock?、?try_lock?),则无其他线程能获取该锁(包括共享的)。

仅当任何线程均未获取独占性锁时,共享锁能被多个线程获取(通过?lock_shared?、?try_lock_shared?)。

在一个线程内,同一时刻只能获取一个锁(共享或独占性)。

共享互斥体在能由任何数量的线程同时读共享数据,但一个线程只能在无其他线程同时读写时写同一数据时特别有用。

shared_mutex?类满足共享互斥体?(SharedMutex)?和标准布局类型?(StandardLayoutType)?的所有要求。

以上是cppreferenced的原文。翻译一遍就是这样的逻辑

当Mutex是shared_mutex?的时候

1.当有函数使用共享锁时,能够与其他享有共享锁的函数也能并发同步执行。而和所有独占锁的函数是互斥的。

2.当有一个函数使用独占锁时,其他所有的用同一个Mutex带锁的函数都是与其互斥的。

那么这个情况就和我所遇到的需求是完全一致的。

已知的独占锁

lock

锁定互斥,若互斥不可用则阻塞 (公开成员函数)

try_lock

尝试锁定互斥,若互斥不可用则返回 (公开成员函数)

unlock

解锁互斥 (公开成员函数)????????????????std::unique_lock自动加锁和解锁std::lock_guard自动加锁和解锁

已知的共享锁

共享锁定

lock_shared

为共享所有权锁定互斥,若互斥不可用则阻塞 (公开成员函数)

try_lock_shared

尝试为共享所有权锁定互斥,若互斥不可用则返回 (公开成员函数)

unlock_shared

解锁互斥(共享所有权) (公开成员函数)std::shared_lock自动加锁和解锁
3.代码验证

以下代码是本人在vs2019,c++最新标准下运行的。

可以直接复制过去看效果,也可以自己稍作修改进行验证

#include <iostream> #include <string> #include <mutex> #include <thread> #include <shared_mutex> #include <Windows.h> std::shared_mutex g_sMutex; void writeTime(const std::string funName ,int time) { for (size_t i = 1; i < time; i++) { std::string outPut = funName + ":" + std::to_string(time); std::cout << outPut << std::endl; Sleep(1000); } } void shared_1(int seconds) { std::shared_lock<std::shared_mutex> theLock(g_sMutex); writeTime("shared_1" , seconds); } void shared_2(int seconds) { std::shared_lock<std::shared_mutex> theLock(g_sMutex); writeTime("shared_2", seconds); } void unique_1(int seconds) { std::unique_lock<std::shared_mutex> lck(g_sMutex); writeTime("unique_1", seconds); } void unique_2(int seconds) { std::unique_lock<std::shared_mutex> lck(g_sMutex); writeTime("unique_2", seconds); } void nomralSuo(int seconds) { std::lock_guard<std::shared_mutex> lck(g_sMutex); writeTime("nomralSuo", seconds); } int main() { std::vector<std::thread> vecThread; vecThread.push_back(std::thread(nomralSuo, 10)); vecThread.push_back(std::thread(shared_1, 10)); vecThread.push_back(std::thread(shared_2, 10)); vecThread.push_back(std::thread(unique_1, 10)); vecThread.push_back(std::thread(unique_2, 10)); for (auto & oneThread : vecThread) { oneThread.join(); } }


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #C #读写锁 #原先是 #stdmutex #1