BOOST源码笔记(5) - 最小的代价实现同步-无锁编程,看boost中的interlocked_bit_test_and_set实现

boost并发编程boost::atomic boost并发编程 三个用于并发编程的组件: atomic,thread,asio(用于同步和异步io操作) 1. atomic,封装了不同计算机硬件的底层操作原语,提供了跨平台的原子操作功能,解决并发竞争读写变量的困扰。 包含头文件, atomic可以把对类型T的操作原子化,T的要求: 1.标量类型,(算数,枚举,指针) 2.只有平凡拷贝/转移构造、赋值和析构函数的类,并且 阅读详情

如题,如何用最小的代价来实现同步呢,即无锁编程(主要是使用原子操作替代锁来实现对共享资源的访问保护),

我们来看看下面的代码。

首先,我们需要是在这个函数内部对地址x中的值进行位测试并将其对应的位置位。  这里的关键是我们必须先读出*x的值,作位或运算之后,将得到的值对*x赋值。而在多线程环境中,在读出*x后也许有另外的线程对*x进行写操作,这样在给*x赋值的时候就会把对旧的值位或的结果赋给*x,造成错误。

 

这里boost是采用一个循环,将读出的值先保存,这样,读出后的值就为一个不变量,然后计算位或,当然也为不变量。接着用win32中的atom函数interlockedCompareExchange()来对比*x是否在被读出值后改变,如果没改变,则赋值;反之,则更新被保存的变量,再重复判断,直到第前面的情况发生。

 

也许有人会说,如果我这样写呢,                   

long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,*x|value,*x);

是不是就可以避免读和写不一致。错!你这样还是读了共享变量,而且是2次!2次读出的值都可能不一样,使得可能被位或地值都不一致。而且是在进入atom函数后才是同步代码,而读共享变量值得时候是在函数外部,还需要压栈,完全可能不同步。

 

inline bool interlocked_bit_test_and_set(long* x,long bit)
            {
                long const value=1<<bit;
                long old=*x;
                do
                {
                    long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old|value,old);
                    if(current==old)
                    {
                        break;
                    }
                    old=current;
                }
                while(true);
                return (old&value)!=0;
            }

 

以上的函数所用的方法保证了对一个共享值的读-针对读出的值作操作-将操作后的值写回,这3步能够保持同步。我可以类举出win32中interlockedExchangeAdd() <即i++>的实现方法:

 

inline void interlockedExchangeAdd(long* x)
            {
                long old=*x;
                do
                {
                    long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old + 1,old); //

比较并交换操作的作用是在一个原子操作内,先将目标值和老的值进行比较,如果相等就将新的值赋给目标变量。目的是为了防止将新的值赋给目标变量前,在读写操作之间目标变量遭到其他线程的修改。


                    if(current==old)
                    {
                        break;
                    }
                    old=current;
                }
                while(true);
            }

 

 

以上就是lock-free编程中的经典的CAS(compare and swap)的实现,除此外Lock-Free编程还有三大优点:

  • 线程中止免疫:杀掉系统中的任何线程都不会导致其它线程被延迟。
  • 优先级倒置免疫:所谓“优先级倒置”就是指一个低优先级线程持有了一个高优先级线程所需要的互斥体。这种微妙的冲突必须由OS内核来解决。而等待无关和锁无关算法则对此免疫。
  • 死锁免疫:因为没有使用锁,所以也就不存在死锁的可能。但是乐观的并发,可能会导致活锁。

虽然Lock-Free编程非常困难,但是它通常可以带来比基于锁编程更高的吞吐量。所以Lock-Free编程是大有前途的技术。它在线程中止、优先级倒置以及信号安全等方面都有着良好的表现。

 

但是CAS会出现ABA问题,这就不在我们的讨论范围内了。转个ABA的解决:

 

即定义额外的标识之类得方法来区别第一次A和第二次的A(不重用A),使得CAS能够察觉变化。

 

 

三大主流交易接口实战指南:XTP、CTP与数字货币API的实盘接入解析 本文深入解析了量化交易系统实现实盘交易的关键环节,聚焦于三大主流交易接口的实战接入。详细介绍了证券领域的XTP、期货领域的CTP以及数字货币交易所API的核心特性、代码封装要点与风控实践,并提供了多市场接口整合的统一架构方案,为开发者打通量化交易的“最后一公里”提供了一份接地气的实战指南。 阅读详情

相关推荐

MATLAB机械臂轨迹规划:在关节空间中生成多项式轨迹以及 jtraj函数(内容超详细讲解)

matlab机器人仿真,关节空间多项式轨迹生成

qq_40969179的博客 1万+

明明白白自旋锁

标 题: 明明白白自旋锁 作 者: achillis 时 间: 2008-10-12,13:39:46 链 接:http://bbs.pediy.com/showthread.php?t=74502 自某日看了iceboy和MJ0011关于多处理器同步的一些讨论,才发现原来我对自旋锁的理解也有一定错误,还好现在明白了~~为了加深理解,就深入分析了一下自旋锁的实现,一篇小小的自旋锁分析文

kingswb的博客 1192

openEuler 22.03 LTS SP4离线安装UKUI桌面全攻略(附依赖包下载)

本文提供openEuler 22.03 LTS SP4系统离线安装UKUI桌面环境的完整实战指南。针对无网络环境,详细解析了利用dnf工具下载依赖包、配置离线软件源、处理依赖冲突及安装后优化的全流程,并附带了关键依赖包资源,帮助运维人员高效完成图形化部署。

c7d8e9的博客 482

boost学习与应用笔记之一:Boost.Atomic

Presenting Boost.Atomic Boost.Atomic is a library that provides atomic data types and operations on these data types,  as well as memory ordering constraints required for coordinating multiple thr

北雨南萍 3211

从圆形到椭圆:CenterNet中高斯热图半径的自适应优化策略

本文深入探讨了CenterNet目标检测模型中高斯热图生成策略的优化,针对传统圆形高斯核在处理长宽比差异大目标时的局限性,提出了自适应椭圆高斯核的解决方案。通过数学推导和代码实战,详细阐述了如何根据目标边界框尺寸动态计算椭圆长短轴半径,生成更贴合目标几何形状的热图监督信号,从而有效提升模型,尤其是对无人机、车辆等不规则目标的定位精度。

alice7model的博客 985

[内网基础] 内网基础知识 —— Windows 工作组

在一个大型单位里,可能有成百上千台计算机互相连接组成局域网,如果不对这些计算机进行分组,网络的混乱程度是可想而知的。Windows 为了解决这一问题,就产生了工作组(Work Group)这个概念。Windows 工作组尝试将不通的计算机按功能(或部门)分别列入不同的工作组,例如技术部的计算机都列入 “技术部” 工作组、行政部的计算机都列入 “行政部” 工作组。要想访问某个部门的资源,只要在 “网络” 里双击该部门的工作组名,就可以看到该部门里的所有计算机了。

Blue17 の 小窝 1604

bittest & bittestandset

// bittest.cpp// processor: x86, IPF, x64#include <iostream>#include <stdio.h>#include <intrin.h>//for _bittest() & _bittestandset()typedefunsignedcharbyte;//取32位整形数组的第i(i从0开...

weixin_30563917的博客 295

一文吃透 SAP HANA Service Broker:原理、架构与落地实践

摘要:SAP HANA Service Broker 作为云原生开发的关键组件,通过标准化流程管理 HDI 容器与服务实例的生命周期,实现数据库资源的自动化配置与安全隔离。它采用服务目录、服务计划和绑定机制,将连接凭据注入应用环境变量,避免硬编码风险。在实际应用中,需根据模块生命周期决定共享或隔离容器,并通过跨容器访问模式实现安全数据共享。典型案例展示了电商平台的多模块协同与SaaS租户隔离场景,验证了其在提升运维效率与安全合规方面的价值。最佳实践强调以生命周期划边界、最小权限原则和HTTPS安全传输,为企

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 225

test_bit、set_bit和clear_bit

//将addr的第nr(nr为0-31)位置值置为1; //nr大于31时,把高27的值做为当前地址的偏移,低5位的值为要置为1的位数 extern __inline__ int set_bit(int nr,int * addr) { int mask, retval; addr += nr >> 5; //nr大于31时,把高27的值做为当前地址的偏移, mask = 1 << (nr &amp...

Android 系统开发 1456

【Python音频处理】syncstart 计算媒体文件同步时间偏移

syncstart是一个强大的工具,它简化了多媒体文件的音视频同步过程,特别适用于多设备录制的媒体内容。在使用命令行工具时,可以根据实际需求灵活调整参数,如归一化、降噪、低通滤波等,以提高同步的精度和效率。通过本文介绍的基本操作和应用示例,可以快速掌握syncstart的使用方法,并将其应用到日常的音视频处理工作中。

Mr数据杨 816

倍福PLC--PERSISTENT断电保持数据和BOOT中各文件对应的解析

将D:\TC3程序\TwinCAT Project146\TwinCAT RT(x86)\Plc 文件夹的中三个替换文件复制到:G:\TwinCAT\3.1\Boot\Plc完成替换,如下图。(2) 找到程序所存的路径,编程电脑的D:\TC3程序\TwinCAT Project146路径下,并选择对应系统平台TwinCAT RT(x86)(3) 控制器断电,拔出内存卡,使用读卡器,在编程电脑中打开:(本次测试读卡器为G盘)(5) 开机完成后,TwinCAT自动运行,当前闪灯频率为50ms。

weixin_41883890的博客 2340

不允许重载函数“_interlockedbittestandreset”的第二个 C 链

编译时遇到的错误及处理方法 不允许重载函数“_interlockedbittestandreset”的第二个 C 链  将vs include file 删除 __MACHINEI(unsigned char _interlockedbittestandset(long volatile *a, long b)) __MACHINEI(unsigned char _interlockedb

TonyAnny专栏 4235

【大数据Java基础-Java基础01】环境搭建(一)Sublime Text3搭建Java编译环境(Windows系统)

1. 首先配置好Java环境变量 我的jdk版本是1.8.0_191,存放目录是C:\Program Files\Java,因此添加以下环境变量 (1)系统变量→新建 JAVA_HOME 变量,变量值为: C:\Program Files\Java\jdk1.8.0_191 (2)系统变量→找到 Path 变量→编辑,末尾加入: ;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin 如果Path变量末尾本身有“;”,则上述路径前面则不需要加“;” (3)系统变量→新建 CL

微信搜:import_bigdata,大数据领域硬核原创作者 553

关于bit操作(bit_set test_bit)

    今天发现一个奇怪的现象,用linux内核的bitops.h里面的bit_set和test_bit居然没有不用汇编的代码快。记录下来,备忘。    下面是可执行程序,THUIRDB暂时没有bitops里面的实现,改用我自己写的实现了。当然bitops里的实现,nr可以很大,而我的代码nr只能是0-63之间的一个数,对THUIRDB的应用来说,足够了。#include "std

pennyliang的专栏 1万+

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

test_and_set_bit

Man page of test_and_set_bit(int nr, volatile void *addr)这样描述它的功能: "Set a bit and return its old value"  nr -- Bit to set  addr -- Address to count from 注意:nr是需要设置的“哪一位”,而不是将ad

helloworlddm的博客 3077

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

unsigned char _interlockedbittestandset(long volatile *a, long b)问题

因为某种原因,使用了 MSVC的编译器, 但是没有使用 visual studio IDE, 这时候, 如果还使用 旧的SDK package, 这时候在同时 Include intrin.h 和  WinNT.h 的时候, 就会出现这个错误: __MACHINEI(unsigned char _interlockedbittestandset(long volatile *a, long

一亩半分地 2169

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

_InterlockedAnd _InterlockedOr等原子级安全运算

http://msdn.microsoft.com/en-us/library/windows/desktop/ff471407(v=vs.85).aspx 内部与-安全操作 _InterlockedAnd  _InterlockedOr 在 VS2010 中,在x86  x64编译模式下 ,InterlockedAnd 与_InterlockedAnd 的使用问题

浴血重生-学习空间 2918

_bittest & _bittestandset

C 中的unsigned 类型默认为unsigned int类型。unsigned char为8bit都使用,没有符号位。char < unsigned char < int < unsigned int_bittest, _bittest64 在vs2005以后支持,返回值为unsigned char,如果要得到0或1的值需要进行强制类型转换。检查地址a中,第b位的值是0还是...

weixin_30376509的博客 435

位原子操作

一、理论:1.并发 并发的概念是:多个执行单元同时、并行被执行。 Linux系统是多任务的,很多任务会同时执行。 假如有三个执行单元ABC,共享了内存资源。 执行单元A对Buffer写1000个“a”; 执行单元B对Buffer写1000个“b”; 执行单元C从buffer中读取数据。 如果按照A写→C读→B写→C读,当然没有问题。 但是如果A写→B写→C读,执行单元C就出问题了。 当然比这个复杂...

danwuxie的博客 1040

c++11 std::atomic

reference: c++11 std::atomic https://www.jianshu.com/p/b7a2b36f43d9 使用原子的变量,++ 和 -- 的次数相同,最终为0; 没有使用原则的变量,++ 和 -- 的次数不相同,最终不为0; c++新特性之std::atomic https://blog.youkuaiyun.com/delongwang520/article/details/79604329 ...

Oliver King 的小窝 621

boost的多线程实现机理

对boost的多线程感觉挺好奇的,所以就追踪了以下。 设置在 下面,为了调用windows api,boost是这么做的 # include namespace boost { namespace detail { namespace w

关注3d图形技术,移动互联网 1709

并发学习-【转】深入理解并发之CompareAndSet(CAS)

程老师原文地址:http://flychao88.iteye.com/blog/2269438 原文如下: 一、CAS简介 CAS:Compare and Swap, 翻译成比较并交换。 java.util.concurrent包中借助CAS实现了区别于synchronouse同步锁的一种乐观锁,使用这些类在多核CPU的机器上会有比较好的性能. CAS有3个操作数,内存值V,旧的预期...

bohu83的博客 1万+

7.3 实现顺序死锁代码

简单顺序死锁的条件 1、两个线程1,2 2、两个资源a,b 3、两个线程先获取不同的资源(使用Thread.sleep) demo public class TestDeadLock { static class CustomerA extends Thread{ Object a; Object b; public CustomerA(Object a, Object b) { this.a = a; ...

一点光辉的博客 173

Java里的CompareAndSet(CAS)

Atomic 从JDK5开始, java.util.concurrent包里提供了很多面向并发编程的类. 使用这些类在多核CPU的机器上会有比较好的性能. 主要原因是这些类里面大多使用(失败-重试方式的)乐观锁而不是synchronized方式的悲观锁. 今天有时间跟踪了一下AtomicInteger的incrementAndGet的实现. 本人对并发编程也不是特别了解, 在这里就是做

fangchengimz的博客 344
上一篇: BOOST源码笔记(4) - thread_move_t概念
下一篇: BOOST源码笔记(6) - 无安全保证的随意转换~~~force_cast
daeees
博客等级 码龄19年 6粉丝 51原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值