Boost Lockfree「建议收藏」

Boost Lockfree「建议收藏」BoostLockfreeflyfish2014-9-30为了最大限度的挖掘并行编程的性能考虑使用与锁无关的数据结构来编程与锁无关的数据结构不是依赖于锁和互斥来确保线程安全。Lockfree的重要操作就是CAS(CompareAndSet)原子操作原子操作就是多个线程访问同一个资源时,有且仅有唯一一个线程对该资源进行操作BOOST中的宏定义BOOST_

大家好,又见面了,我是你们的朋友全栈君。

Boost Lockfree

flyfish 2014-9-30

首先lockfree ,如何去理解这个free

引用自《英语学习漫谈》

 free诚然可以当自由来理解,但自由并没有触及到 free的核心概念,所以你在很多场合看到free的时候,会产生理解困难。那年迈阿密热打进NBA总决赛,比赛转播期间电视上不停地打出一个广告,说佛罗里达要成为一个 tobaccofree的州,这显然不是说你在佛罗里达可以随便抽烟,而是此州(所有公共场所)不能抽烟;最近美国的几家航空公司开始考虑在飞机上设立childrenfree区,就是不让小孩儿进去,免得打搅其他旅客;美国的drugstore里出售的软饮料包装上可能会有“alcohol free”的字样,就是说不含酒精。  “自由”是free的引申义。free的核心概念是“无……”。“无”的一般来说是一些会让你不开心的东西,诸如负担、负税、责任、包袱、费用、规则、担忧、焦虑……“自由”本身也是没有负担和阻碍的意思。当free出现在一个词后面的时候,如 alcohol free,就是要把这个词代表的东西干掉了,这个用法才接近free的核心含义。英美人看到free,潜意识只会想到它要干掉的东西,所以free本身并不是一个完整的词。  现在你明白“carefree”是怎么回事了吧?不担心,不关心,不操心,怎会不一身轻松呢?但是,绝对的carefree是不可能的,你不care别人,也没有人会care你。  我曾经犯过把“free”当成“自由”来理解的错误。有一次吃盖浇饭碰到一个美国人,我跟他搭讪,说:“美国是一个free的国家。”他没听听懂,问:“什么free?”我一开始心想他连美国精神都不知道,但马上反应过来了,赶紧加了一句:“free去干很多事。”他这才明白。可见“free”单独出现时并不代表“自由”,“自由”只是“free”可以达到的许多结果之一。

为了最大限度的挖掘并行编程的性能考虑使用与锁无关的数据结构来编程

与锁无关的数据结构不是依赖于锁和互斥来确保线程安全。


Lockfree的重要操作就是CAS(Compare And Set)原子操作

原子操作就是多个线程访问同一个资源时,有且仅有唯一 一个线程对该资源进行操作

BOOST中的宏定义

BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B

BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B

cmpxchg:比较并交换,也就是

伪代码

bool CAS(int* p,int nOld,int nNew)
{
	bool bRet=false;
	if (*p == nOld)
	{
		*p=nNew;
		bRet=true;
	}


	return bRet;
}


CAS操作产生的ABA问题

两个线程P1和P2

P1读变量A

P1中断,

P2开始运行,读变量A,更改为B,又更改为A,

P2执行完

P1继续操作,A还是A,P1认为什么也没有发生

例如

栈 (Stack)是一种后进先出(last in first off,LIFO)的数据结构,只允许在栈顶操作。

假设有一个栈,有三个元素

A

B

C

线程P1,P2对该栈进行操作

P1 读栈顶A

P1 中断

P2 开始运行,A出栈,B出栈,A压栈(删除B)

P1 继续执行,A还是A

P1认为该栈的结构还是ABC,而此时栈里只有两个元素

就像小时候在家偷看电视,防止电视过热被父母发现,看一会儿就关上,等会儿再看。

当听见开门的声音时,以迅雷不及掩耳之势,换回开始的频道,调回音量图标的格数,关上电视,放回遥控器原来的位置并注意遥控器的朝向来表明没有看电视。


64位平台的处理方案

看boost::lockfree::detail::tagged_ptr代码

解决方式1

文件tagged_ptr_dcas.hpp

简化代码

template <class T>
class  tagged_ptr
{
public:
    typedef std::size_t tag_t;
protected:
    T * ptr;
    tag_t tag;
};

ABA问题解决方式是一个std::size_t类型的tag+指针,但不是所有平台都支持。


解决方式2

文件tagged_ptr_ptrcompression.hpp

简化代码

#if defined (__x86_64__) || defined (_M_X64)
class tagged_ptr
{
    typedef boost::uint64_t compressed_ptr_t;


public:
    typedef boost::uint16_t tag_t;


private:
    union cast_unit
    {
        compressed_ptr_t value;
        tag_t tag[4];
    };


    static const int tag_index = 3;
    static const compressed_ptr_t ptr_mask = 0xffffffffffffUL; //(1L<<48L)-1;
......
}


#else
#error unsupported platform
#endif

早期X86-64处理器不支持cmpxchg16b指令

在X86-64平台上,48位是地址,剩下的16位是ABA预防tag

代码

static const compressed_ptr_t ptr_mask = 0xffffffffffffUL; //(1L<<48L)-1;

0xffffffffffff二进制就是48个1。

tag就像一个版本号,通过tag,线程可以知道操作的数据已经发生了变化。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/161677.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 计算机的存储容量一般用什么来表示_计算机常用的存储容量单位

    计算机的存储容量一般用什么来表示_计算机常用的存储容量单位存储容量是指存储器可以容纳的二进制信息量,用存储器中存储地址寄存器MAR的编址数与存储字位数的乘积表示。中文名存储容量所属学科计算机科学与技术存储容量单位简介语音网络上的所有信息都是以“位”(bit)为单位传递的,一个位就代表一个0或1。每8个位(bit)组成一个字节(byte)。字节是什么概念呢?一个英文字母就占用一个字节,也就是8位,一个汉字占用两个字节。一般位简写为小写字母“b”,字节简写为…

    2022年10月6日
    0
  • 整理了十五道为数不多的tomcat面试题,错过就没了!

    整理了十五道为数不多的tomcat面试题,错过就没了!当容器启动时,会读取在webapps目录下所有的web应用中的web.xml文件,然后对xml文件进行解析,并读取servlet注册信息。然后,将每个应用中注册的servlet类都进行加载,并通过反射的方式实例化。(有时候也是在第一次请求时实例化)在servlet注册时加上如果为正数,则在一开始就实例化,如果不写或为负数,则第一次请求实例化。

    2022年6月6日
    29
  • android内置存储器memory和第三方外部存储disk管理

    android内置存储器memory和第三方外部存储disk管理

    2022年1月9日
    37
  • redhat安装yum源_redhat yum源

    redhat安装yum源_redhat yum源Yum是RedHat和基于RedHat的Linux发行版中的包管理器,它允许您管理RedHat系统上软件的各个方面。你不会在这里详细学习Yum命令,相反,这个Yum备忘单为您提供了所有主要Yum包管理器命令及其各自功能的快速简单的概述。安装、卸载和升级包以下是用于安装、删除和更新软件包的Yum命令。install:从yum存储库安装软件包sudoyuminstallnginxremove:删除已安装的软件包及其依赖项sudoyumre

    2022年10月29日
    0
  • springboot的启动流程图_springboot运行流程

    springboot的启动流程图_springboot运行流程文章目录前言springboot启动流程图第一部分newSpringApplication()第二部分工厂对象构建实例第三部分SpringApplication.run(启动此应用)第四部分SpringApplicationRunListener第五部分banner彩蛋前言研究springboot启动的整个流程。springboot启动流程图第一部分newSpringApplication()第二部分工厂对象构建实例第三部分SpringApplication.

    2022年8月20日
    5
  • Wix 安装部署(五) Bootstrapper 捆绑安装

    Wix 安装部署(五) Bootstrapper 捆绑安装原文:Wix安装部署(五)Bootstrapper捆绑安装   Wix的xml配置确实很费劲,忍不住有点像吐槽一下,前四篇完成的功能在WindowsInstaller中通过配置能很快的弄出来。可惜有很多加了锁的功能在InstallShieldLimitedEdition版本中是用不了的。但基本满足安装需求了。按照这个目录(下图)一个一个去配,配出来的也像样了(这里就不说了)。…

    2022年7月20日
    11

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号