首页 > 编程语言 >C++17里面的读写锁(shared_lock读锁,unique_lock写锁)

C++17里面的读写锁(shared_lock读锁,unique_lock写锁)

时间:2023-12-29 18:34:09浏览次数:48  
标签:std 10 17 写锁 lock 读写 C++ 读锁

C++标准库本身没有直接提供读写锁,但C++11引入了一些工具,例如std::shared_mutex(C++14引入的,C++17之前的标准库中可能不支持)以及相关的读锁定(std::shared_lock)和写锁定(std::unique_lock)机制,用于实现读写锁的功能。

下面是一个简单的示例,演示如何使用std::shared_mutex实现读写锁:

 

文件名称是  test_rw_lock.cpp

在C++17下面编译的代码。

编译命令:

g++ test_rw_lock.cpp --std=c++17 -o wr.bin -l pthread

 

这里我们创建了10个写的线程,来执行fun1里面的方法,给iCount做自增操作。

我们创建了10个读的线程,来执行fun2里面读取的方法,输出iCount里面的值。

 

验证写锁:(写锁要能够解决写冲突)

1.不加锁,打印程序执行结果,预期结果是1000*10;多次执行程序,发现结果不是预期的值。

2.加读锁,打印程序执行结果,预期结果是1000*10;多次执行程序,发现结果不是预期的值。

3.加写锁(注释读锁),打印程序执行结果,预期结果是1000*10;多次执行程序,发现结果满足预期的值。

因此可以验证,写锁是成功的。

写锁避免了多线程写的冲突。

 

验证读锁:(验证多次读取功能,多次加读锁功能)

 1.加读锁,打印程序结果,在日志里面看结果。如果有现成读取数值相同,说明读锁是正常的。(读锁要支持多次读取)

 执行程序的时候,可以执行下面的命令,把数据导出到 文本里面。

我们如果在日志里面看到的fun2里面输出了同样的数值,说明2个线程都读取到了同一个数值,说明加多个读锁是没有冲突,没有问题的。说明读锁成功。

(wr.bin是我们编译生成的文件,“>”操作符是导出数据到文本。)

./wr.bin  > a1.log 

 

这个读写锁,在C++17的标准款中才开始支持。使用这里的读写锁,需要升级gcc版本。

这里有一个自己写的读写锁功能。移植了tars里面的读写锁代码。他不需要C++17标准款。

对于版本较低的gcc,可以考虑这里的代码。地址:https://github.com/liangzai90/henry-util

 
#include <iostream>
#include <mutex>
#include <shared_mutex>
#include <thread>
#include <vector>

std::shared_mutex m_mutex;
int iCount = 0;

// test write lock
void fun1() {
    for(int i=0;i<1000;++i) {
        //std::shared_lock<std::shared_mutex> lock(m_mutex); //read lock
        std::unique_lock<std::shared_mutex> lock(m_mutex); //write lock
        ++iCount;
    }
}

// test read lock
void fun2(){
    for(int i=0;i<1000;++i) {
        std::shared_lock<std::shared_mutex> lock(m_mutex); //read lock
        std::cout<<"read val is:"<< iCount << std::endl;
    }
}

int main() {

    //当你想要将线程放入std::vector容器时,你需要使用指向线程的指针或std::thread的移动语义,
    //因为std::thread对象不能被拷贝。
    //std::vector<std::thread> vec_ths;
    
    //std::thread threads[10];
    // 是使用数组方式创建一个包含10个std::thread对象的数组。
    //这个数组用于存储线程对象,每个元素代表一个线程
    constexpr size_t numThreads = 10;
    std::thread  ths[numThreads];

    std::thread  r_ths[numThreads];
    for(int i=0;i<numThreads;++i) {
        ths[i] = std::thread(fun1);
        r_ths[i] = std::thread(fun2);
    }

    for(int i=0;i<numThreads;++i) {
        ths[i].join();   // test write lock
        r_ths[i].join(); // test read lock.
    }

    std::this_thread::sleep_for(std::chrono::milliseconds(6666));
    std::cout<<std::endl<<"finished iCount:"<<iCount<<std::endl;

    // g++ test_rw_lock.cpp --std=c++17 -o wr.bin -l pthread
    return 0;
}

 

标签:std,10,17,写锁,lock,读写,C++,读锁
From: https://www.cnblogs.com/music-liang/p/17935504.html

相关文章

  • LockBit勒索攻击大杀四方,超千家企业被攻击,金融、能源等成重灾区
    近期以来,针对金融、能源等关基行业的勒索攻击,又开始全球发酵。不久前,某金融机构在官网发布声明称遭受了勒索软件攻击,导致部分系统中断,LockBit组织确认对本次攻击负责。安全专家提醒,LockBit勒索家族号称加密最快的勒索软件,包括波音公司在内,超过千家企业遭受LockBit勒索软件攻击。金......
  • 1768
    我的答案:classSolution{public:stringresult;inti=0,j=0;stringmergeAlternately(stringword1,stringword2){if(word1.length()<1||word2.length()>100){return0;}if(word1.size()<word2.size()){while(i......
  • 无涯教程-Java NIO - FileLock(文件锁)
    JavaNIO支持并发和多线程,这使它能够同时处理在多个文件上运行的多个线程,但是在某些情况下,无涯教程要求文件不能被任何线程共享并且不可访问。为了满足这种要求,NIO提供了FileLock的API,该API用于提供对整个文件或部分文件的锁定,以使该文件或其部分不会共享或不可访问。为了提供或......
  • ReentrantReadWriteLock源码阅读
    ReentrantReadWriteLock源码阅读目录ReentrantReadWriteLock源码阅读简介例子代码分析总览Syncstate定义lockcount和holdcountSync.HoldCounter类Sync类其他成员变量tryAcquiretryReleasetryAcquireSharedfullTryAcquireSharedtryReleaseSharedtryWriteLocktryReadLockSync类分......
  • VMware ESXi 8.0U2 macOS Unlocker & OEM BIOS 标准版和厂商定制版
    VMwareESXi8.0U2macOSUnlocker&OEMBIOS标准版和厂商定制版ESXi8.0U2标准版,Dell(戴尔)、HPE(慧与)、Lenovo(联想)、Inspur(浪潮)等定制版作者主页:sysin.org2023-09-22,VMwarevSphere8.0U2发布,本站定制镜像相应更新。新增功能详见:VMwarevSphere8Update2新增......
  • 17 SPI驱动HC595点亮数码管
    软件版本:VIVADO2021.1操作系统:WIN1064bit硬件平台:适用XILINXA7/K7/Z7/ZU/KU系列FPGA登录米联客(MILIANKE)FPGA社区-www.uisrc.com观看免费视频课程、在线答疑解惑!1概述前面课程我们编写SPI通信FPGA的收发程序,那么这一节课,我们将展示下SPI接口的应用,使用SPI接口的74HC595......
  • Cisco® Catalyst® 8000V 边缘软件(虚拟路由器)IOS XE 17.12.1 发布
    Cisco®Catalyst®8000V边缘软件(虚拟路由器)IOSXE17.12.1发布CiscoCatalyst8000vEdgeSoftware,IOSXEReleaseDublin-17.12.1aEDCisco®Catalyst®8000V边缘软件-虚拟路由器作者主页:sysin.orgCisco®Catalyst®8000V边缘软件(Catalyst8000V)是一款虚拟路由......
  • Cisco Catalyst 8000 边缘平台系列 IOS XE 17.12.01 发布
    CiscoCatalyst8000边缘平台系列IOSXE17.12.01发布CiscoCatalyst8000SeriesEdgePlatforms,IOSXEReleaseDublin-17.12.01aEDCiscoCatalyst8000边缘平台系列作者主页:sysin.orgCiscoCatalyst8000:随心所欲访问位于云、数据中心和边缘的混合型应用和多云应用。特性......
  • Apple Safari 17.1 - macOS 专属浏览器 (独立安装包下载)
    AppleSafari17.1-macOS专属浏览器(独立安装包下载)适用于macOSVentura和macOSMonterey的Safari浏览器17作者主页:sysin.org之前Safari浏览器伴随macOS更新一起发布,需要系统更新才能体验到新版,现在库克终于带来了独立安装包,无需更新系统也可感受最新的卓越Web体......
  • 17.高级控件交互方法
    使用场景 使用场景对应事件复制粘贴键盘事件拖动元素到某个位置鼠标事件鼠标悬停鼠标事件滚动到某个元素滚动事件使用触控笔点击触控笔事件(了解即可)https://www.selenium.dev/documentation/webdriver/actions_apiActionChains解析 ......