博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Atitit。Cas机制 软件开发 编程语言 无锁机制 java c# php
阅读量:5153 次
发布时间:2019-06-13

本文共 2006 字,大约阅读时间需要 6 分钟。

AtititCas机制 软件开发 编程语言 无锁机制 java c# php

 

1为什么需要无锁操作1

2硬件支持 cas  atomic2

3无锁编程(Lock-Free)就是在某些应用场景和领域下解决以上基于锁机制的并发编程的一种方案。3

4Volatile  内存屏障(Memory Barriers),就是它让一个处理器内的内存状态对其他处理器可见。 3

5参考3

 

 

1. 为什么需要无锁操作

 

在某些时刻,你给这个变量赋一个64位的值。

 

1

2

3

4

void storeValue()

{

     sharedValue = 0x100000002;

}

 

当你在32位的x86环境下使用GCC来编译这个函数时,将会生成如下机器码。

 

1

2

3

4

5

6

7

$ gcc -O2 -S -masm=intel test.c

$ cat test.s

      ...

      mov DWORD PTR sharedValue, 2

      mov DWORD PTR sharedValue+4, 1

      ret

      ...

 

这个时候你就会看到,编译器会使用两个单独的机器指令来完成这个64位的赋值。第一条指令设置低32位的0×00000002,第二条指令设置高32位的0×00000001.非常明显,这个赋值操作是非原子的。如果共享变量同时被不同的线程存取,就会出现很多错误:

作者::  (attilax)>>> 绰号:老哇的爪子 ( 全名::Attilax Akbar Al Rapanui 阿提拉克斯 阿克巴 阿尔 拉帕努伊 ) 汉字名:艾龙,  EMAIL:1466519819@qq.com

转载请注明来源: http://www.cnblogs.com/attilax/

 

同时读取sharedValue会带给它一系列的问题:

 

1

2

3

4

5

6

7

8

9

10

11

12

uint64_t loadValue()

{

      return sharedValue;

}

 

$ gcc -O2 -S -masm=intel test.c

$ cat test.s

      ...

      mov eax, DWORD PTR sharedValue

      mov edx, DWORD PTR sharedValue+4

      ret

      ...

 

这里也一样,编译器会使用两条机器指令来执行这个加载操作:第一条读取低32位到eax,第二条读取高32位到edx。在这种情况下,如果对于sharedValue进行同时存储则会发现,它将导致一个读撕裂——即使这个同时存储是原子的。

 

众所周知,在x86环境下,如果内存操作数是自然对齐的,那么一个32位的mov指令就是原子的,但如果不是自然对齐,那么将是非原子的。换句话说,原子性的保证仅仅是当一个32位整数的地址正好是4的倍数的时候。

2. 硬件支持 cas  atomic

原子性不可能由软件单独保证--必须需要硬件的支持,因此是和架构相关的。在x86 平台上,CPU提供了在指令执行期间对总线加锁的手段。CPU芯片上有一条引线#HLOCK pin,如果汇编语言的程序中在一条指令前面加上前缀"LOCK",经过汇编以后的机器代码就使CPU在执行这条指令的时候把#HLOCK pin的电位拉低,持续到这条指令结束时放开,从而把总线锁住,这样同一总线上别的CPU就暂时不能通过总线访问内存了,保证了这条指令在多处理器环境中的原子性。

 

软件级的原子操作,包括两大类系统调用,一类是基于对整数进行操作的atomic_set/and/inc,一类是针对单独的位进行操作的set/clear/change_bit,它们大部分都是基于硬件层面的CAS的指令实现的。

 

各种开发语言中(c,c++,java)基于操作系统提供的接口也都封装实现了对应的原子操作api,所以开发者完全可以直接调用各个开发语言提供的接口实现无锁程序。

3. 无锁编程(Lock-Free)就是在某些应用场景和领域下解决以上基于锁机制的并发编程的一种方案。

 

4. Volatile  内存屏障(Memory Barriers),就是它让一个处理器内的内存状态对其他处理器可见。

 

volatile

volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值。volatile很容易被误用,用来进行原子性操作

 

5. 参考

原子操作 vs 非原子操作 博客 伯乐在线.htm

内存屏障(Memory Barriers) 博客 伯乐在线.htm

【原创】无锁编程技术及实现-黑夜路人-微头条(wtoutiao.com).htm

javavolatile关键字的含义 - God Is Coder - 博客园.htm

 

转载于:https://www.cnblogs.com/attilax/p/5324217.html

你可能感兴趣的文章
Effective C++ 读书笔记(五)
查看>>
Linux命令:sed
查看>>
jQuery选项卡
查看>>
android4.4 重启的开机不播放开机铃声,按power键的开机播放开机铃声
查看>>
MySQL innodb的锁机制解读
查看>>
单击EasyUI的datagrid行时不选中
查看>>
CategoryAndExtension(一)
查看>>
IP子网的几个认识
查看>>
表单提交中的input、button、submit的区别(转来学习)
查看>>
java字符串分割的小练习
查看>>
冬雷震震
查看>>
SYSU每周一赛(13.03.16)1002
查看>>
初步了解 Dubbo 初始化,加载
查看>>
Python3网络爬虫——一、什么是爬虫
查看>>
Array.from()和Array.of()
查看>>
10.17-JavaScript
查看>>
网络通讯框架MINA和XSCOCKET的简单比较
查看>>
【iOS开发-91】GCD的同步异步串行并行、NSOperation和NSOperationQueue一级用dispatch_once实现单例...
查看>>
Opencv on Ubuntu (from Ubuntu)
查看>>
从Ubuntu12.04升级到Ubuntu 14.04之后,系统将无法启动
查看>>