保证const成员函数的线程安全(C++11/14)—————C++2.0第十一讲_c++线程安全const_繁星蓝雨的博客-程序员秘密

技术标签: C++基础和特性  c++  atomic  多线程  mutex  数据竞争  

0 结论

  • 保证const成员函数的线程安全,确定它们不会用在并发的语境中;
  • 运用std::atomic类型的变量会比互斥类型好,但std::atomic仅适用于单个变量或内存区域的操作。

1 论据

当存在数据竞险(由多个线程在没有同步的情况下读写同一块内存)时,

  • 如果单个要求的同步的变量或内存区域,使用std::atomic就足够了;
  • 如果有两个或更多变量或内存区域需要作为一整个单位进行操作时,就要用到互斥变量mutex。

1.1 使用std::atomic

以较小的开销运行。

class TestConst{
    
public:
    double testFunc() const noexcept{
    
        ++callCount;
        std::cout<<callCount<<std::endl;
        return x*y;
    }
private:
    mutable std::atomic<unsigned > callCount{
    0};//
    double x{
    2}, y{
    3};
};

#include<thread>

int main(){
    
    TestConst* p = new TestConst();
    std::thread t(&TestConst::testFunc, p);//&X::do_lengthy_work,&my_x
    std::thread t2(&TestConst::testFunc, p);//&X::do_lengthy_work,&my_x
    t.join();
    t2.join();
    delete p;
    }

如果callCount没有mutable的声明,那么在const函数函数中,就会当作const对象处理。

2 使用互斥变量mutex

由于std::mutex是只移动类型(只能移动不能复制),那么它修饰的变量也将失去复制性。

当使用std::atomic时,

class TestConst{
    
public:
    int cal() const{
    
        return 2;
    }

    int testFunc() const{
    
        if (cacheVaild){
    
            return cacheVaild;
        }else{
    
            auto v1 = cal();
            auto v2 = cal();
            cacheVaild = true;
            return cacheValue = v1+v2;
        }
    }

private:
    mutable std::atomic<bool> cacheVaild{
    false};
    mutable std::atomic<int> cacheValue{
    0};
};

可能出现的问题为:当一个线程调用testFunc()并执行到cacheVaild被置为true,这时另一个另一线程也在调用testFunc(),在其观察到cacheVaild值后,就直接返回了一个没有赋值的cacheValue。

解决方法:

class TestConst{
    
public:
    int cal() const{
    
        return 2;
    }

    int testFunc() const{
    
        std::lock_guard<std::mutex> guard(m);//加上互斥量
        if (cacheVaild){
    
            return cacheVaild;
        }else{
    
            auto v1 = cal();
            auto v2 = cal();
            cacheVaild = true;
            return cacheValue = v1+v2;
        }
    }

private:
    mutable  std::mutex m;
    mutable bool cacheVaild{
    false};//不再具备原子性
    mutable int cacheValue{
    0};//不再具备原子性
};

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_33375598/article/details/119334731

智能推荐

java项目抠图功能实现_抠图接口如何实现_茁壮成长的凌大大的博客-程序员秘密

java项目抠图功能  项目中需要一个上传文字签名并且抠掉背景图的功能,当初第一次听到这个需求时,差点惊掉下巴,我压根都不会觉得java里能实现这功能。但是既然客户需要,那就照办吧。  经过这次功能的实现,我也更加坚定了一个想法,再奇葩的需求,也要先找找方法,不要果断拒绝,要相信Java天下第一,天下第一能有解决不了的事吗?(其实我现在内心已经对学python蠢蠢欲动了,嘿嘿~~~)1.效果图  经过我一番的搜索加改造,与前端小伙伴做了下边的效果。(整的跟PS一样,顿时有了高大上的感觉)  功能

QML快捷键(Shortcut、Keys)_qml 快捷键_龚建波的博客-程序员秘密

(Qt 的 按键输入都是在应用激活时才能触发的,所以要注册系统全局快捷键请用系统 API)0.前言一般情况下,一个按键事件的流程是这样的:Qt接收按键动作并生成一个按键事件 KeyEvent 如果 QQuickWindow 是 active 的,则将按键事件传递给它 按键事件由 scene 传递到 activeFocus 的 Item,如果没有 activeFocus Item,则事件被忽略 如果按键事件被接受,即 accepted=true,则传递结束,否则将一直往父节点传递,知道根.

Safari常用的快捷键_safari控制台快捷键_那天9832的博客-程序员秘密

control+shift+tab/shift+command+[/shift+command+←:显示上一个标签页,其中箭头对空tab无效。control+tab/shift+command+]/shift+command+→:显示下一个标签页,其中箭头对空tab无效。command+L/option(alt)+command+F/fn+control+F5:定位地址栏/聚焦搜索栏。shift+command+G/shift+enter:查找上一个。shift+command+L:侧边栏(书签/阅读)

tensorflow2加载模型并修改模型_峰子_的博客-程序员秘密

def reload_output_layer(model): #model为加载的模型 new_model = keras.Sequential() #获取模型最后一层 old_output_layer = model.layers[-1] #获取最后一层配置文件 old_config = old_output_layer.get_config(...

:nth-child()伪类选择器_js 伪类nth-child_荣默默的博客-程序员秘密

用法:ul li:nth-child(3n+1){color:red;}其中:nth-child(index)括号里的值可以odd、even以及具体的下标,同时也可以是数学表达式,比如3n+1,n+3等。在这里注意的是它针对的是同一级别的元素标签,就是共同拥有同一个父亲。

再现杰奇网站漏洞环境的三道问题_佛性死磕的博客-程序员秘密

1.第二项:修改后缀2.key值在根目录下:key{fd12bd78}3.找了n久,也没找到路径,还是靠猜出来密码:admin

随便推点

网络营销成功案例分析篇:NIKE网络营销案例_一颗kkkk的博客-程序员秘密

网络营销成功案例分析篇:NIKE网络营销案例一、网络营销渠道概述网络营销逐渐成为企业或不可缺的营销手段,而网络营销渠道是网络营销重要一部分。(一)网络营销渠道的概念网络营销,就是以国际互联网为基础,利用数字化的信息和网络媒体的交互性来辅助营销目标实现的一种新型的市场营销方式,网络营销极具发展前景,必将成为21世纪企业营销的主流。网络营销渠道是网络经济时代的一种崭新的营销理念和营销模式,是指借助于互联网络、电脑通信技术和数字交互式媒体来实现营销目标的一种营销方式,是商品和服务从生产者向消费者转移过程

ubuntu下的fcitx设置_fcuvtx_xuyf的博客-程序员秘密

配置文件在~/.fcitx/config下,如果想改变配置,只修改这个文件即可。要指定使用某个输入法,则还要修改这个目录下的tables.conf或/usr/share/fcitx/data/tables.conf这个文件。

NTU RGB + D 120 动作识别数据集 描绘骨架_hsclyy的博客-程序员秘密

“ NTU RGB + D”和“ NTU RGB + D 120”数据集分别包含56,880和114,480个动作样本。两个数据集都为每种样本包括4种不同的数据形式:RGB视频深度图序列3D骨骼数据红外(IR)视频在这里主要先讲解 3D骨骼数据两个数据集中的每个文件/文件夹名称均采用SsssCcccPpppRrrrAaaa的格式(例如S001C002P003R002A013),其中s...

(原创)easyui_datagrid_load中参数为变量的情况处理_easyui datagrid load参数会变吗_d7011800的博客-程序员秘密

Easyui提供了一个searchBox控件; searchBox的回调方法会提供value和name这两个参数;         问题就出现了:查询的时候, 对应后台变量名的是个js的变量;         比如:    addibleAuthorityDatagrid.datagrid('load', {         name : value,         "a

ad域控服务器如何允许软件安装,AD域服务器实现软件安装部署_彷徨的牛的博客-程序员秘密

《AD域服务器实现软件安装部署》由会员分享,可在线阅读,更多相关《AD域服务器实现软件安装部署(2页珍藏版)》请在人人文库网上搜索。1、AD域服务器实现软件安装部署一、发布应用程序 建立安装WINDOWS安装程序包的文件夹 1、请在任何一台服务器上内建立一个文件夹,例如::packages,这个文件夹是要用来存储应用程序的。 、将此文件夹设置为共享,并给一个共享名。因为网络上的用户必须路径来访问,...

推荐文章

热门文章

相关标签