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能够察觉变化。

 

 

COLMAP性能优化实战:如何用GPU加速和并行计算让重建速度提升300% 本文详细介绍了如何通过GPU加速、并行计算和参数调优显著提升COLMAP的三维重建效率。从硬件资源分配到计算流程优化,再到大型数据集的分块处理策略,全面解析了将重建速度提升300%以上的实用技巧,特别适合处理无人机航拍和室内扫描等大规模三维重建项目。 阅读详情

相关推荐

中国IP发展之面面观

谢学军/邱善勤2006-1-25 9:29:28电子经理世界       IP远没有我们当初想象的那么简单   当SoC设计方法学刚刚传到国内的时候,学界为之欢呼雀跃,由于IP/SoC设计技术的使用,可以将发达国家用几年甚至十几年积累起来的设计技术直接为我所用,使中国的集成电路跳过漫长的积累阶段,迅速站到较高的起点上。因此在当时看来,IP/SoC设计技术是我国提升设计水平、发展

klxdmm305的专栏 1188

明明白白自旋锁

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

kingswb的博客 1192

取证实战:当嫌疑人电脑已关机,如何利用EFDD从休眠文件提取BitLocker密钥?

本文详细介绍了如何利用Elcomsoft Forensic Disk Decryptor(EFDD)从休眠文件(hiberfil.sys)中提取BitLocker密钥的实战技术。通过分析休眠文件中的内存快照,取证人员可以突破已关机加密设备的防线,获取关键解密信息。文章涵盖了工具配置、镜像获取、密钥提取及验证等完整流程,并提供了疑难问题解决方案和法律合规建议。

weixin_29315091的博客 343

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

告别理论!手把手教你用Patran/Nastran搞定悬臂翼的颤振分析(附完整模型文件)

本文提供了一份详细的Patran/Nastran悬臂翼颤振分析实战指南,涵盖从几何建模到结果解读的全过程。通过手把手教学和完整模型文件,帮助工程师和学生快速掌握气动弹性分析技术,特别适合需要实际操作的初学者。文章重点介绍了模态分析、气动建模和颤振求解等关键步骤,并提供了常见问题排查和优化建议。

weixin_30879169的博客 493

C++大牛的博客

1. C++大牛的博客     Bjarne Stroustrup的博客: Bjarne Stroustrup’s Homepage Bjarne Stroustrup,不认识的可以去面壁了,没有他,就没有我们现在的饭碗。Bjarne Stroustrup是丹麦人,目前任教于TAMU。他的Homepage和他的书籍The C++ Programming Language一样

程序猿老樊的博客 6244

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

【STM32实物】基于STM32的扫地机器人/小车控制系统设计

扫地机器人系统采用分层结构设计,主要包括底层硬件控制层、中间数据处理层和上层用户交互层。底层硬件控制层负责对各个硬件模块进行控制和数据采集,中间数据处理层负责对采集到的数据进行处理和解算,上层用户交互层负责与用户进行交互并显示系统状态信息。

嵌入式阿齐Archie 1万+

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

【100%通过率】2024华为OD机试真题E卷 C++语言 实现【流浪地球】

流浪地球计划在赤道上均匀部署了N个转向发动机,按位置顺序编号为0~N-1。 1) 初始状态下所有的发动机都是未启动状态; 2) 发动机起动的方式分为“手动启动”和“关联启动”两种方式; 3) 如果在时刻1一个发动机被启动,下一个时刻2与之相邻的两个发动机就会被“关联启动”; 4) 如果准备启动某个发动机时,它已经被启动了,则什么都不用做; 5) 发动机0与发动机N-1是相邻; 地球联合政府准备挑选某些发动机在某些时刻进行“手动启动”,当然最终所有的发动机都会被启动。 哪些发动机最晚被启动呢?

MISAYAONE的博客 4210

基于CNN-LSTM融合模型的环卫车动态称重算法研究:从频率感知到精准质量估计

摘要: 针对环卫车辆动态称重需求,本研究提出一种基于CNN-LSTM融合网络的频率分析方法。通过在实验室构建振动频率采集系统,获取不同载重下的结构响应数据,经MATLAB进行信号处理和特征提取后,建立频率-质量的非线性映射模型。实验表明,该算法在静态和模拟动态场景下平均绝对误差小于1.5%,显著优于传统方法,为环卫车智能化管理提供了高精度实时称重方案。 关键词: 动态称重;深度学习;频率分析;CNN-LSTM;MATLAB。

AI的内部世界的博客 374

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

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

TonyAnny专栏 4235

[毕设项目-大模型微调]现代文翻译文言文【基于LLaMA3.1-8B微调】

教你基于LLaMA3.1-8B微调如何做到现代文翻译文言文

逐梦苍穹的博客 2296

关于bit操作(bit_set test_bit)

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

pennyliang的专栏 1万+

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

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

jre9下载 jdk9

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

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

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

_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、付费专栏及课程。

余额充值