无锁编程 / lock-free / 非阻塞同步

无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步(Non-blocking Synchronization)。
实现非阻塞同步的方案称为“无锁编程算法”( Non-blocking algorithm)。
lock-free是目前最常见的无锁编程的实现级别(一共三种级别)。

为什么要 Non-blocking sync ?

使用lock实现线程同步有很多缺点:
* 产生竞争时,线程被阻塞等待,无法做到线程实时响应。
* dead lock。
* live lock。
* 优先级翻转。
* 使用不当,造成性能下降。
 
如果在不使用 lock 的情况下,实现变量同步,那就会避免很多问题。虽然目前来看,无锁编程并不能替代 lock。

实现级别

非同步阻塞的实现可以分成三个级别:wait-free/lock-free/obstruction-free。
 
wait-free
是最理想的模式,整个操作保证每个线程在有限步骤下完成。
保证系统级吞吐(system-wide throughput)以及无线程饥饿。
截止2011年,没有多少具体的实现。即使实现了,也需要依赖于具体CPU。
 
lock-free
允许个别线程饥饿,但保证系统级吞吐。
确保至少有一个线程能够继续执行。
wait-free的算法必定也是lock-free的。
 
obstruction-free
在任何时间点,一个线程被隔离为一个事务进行执行(其他线程suspended),并且在有限步骤内完成。在执行过程中,一旦发现数据被修改(采用时间戳、版本号),则回滚。
也叫做乐观锁,即乐观并发控制(OOC)。事务的过程是:1读取,并写时间戳;2准备写入,版本校验;3校验通过则写入,校验不通过,则回滚。
lock-free必定是obstruction-free的。

CAS原语

LL/SC, atom read-modify-write
如果CPU提供了Load-Link/Store-Conditional(LL/SC)这对指令,则就可以轻松实现变量的CPU级别无锁同步。
LL [addr],dst:从内存[addr]处读取值到dst。
SC value,[addr]:对于当前线程,自从上次的LL动作后内存值没有改变,就更新成新值。
上述过程就是实现lock-free的 read-modify-write 的原子操作。
 
CAS (Compare-And-Swap)
LL/SC这对CPU指令没有实现,那么就需要寻找其他算法,比如CAS。
CAS是一组原语指令,用来实现多线程下的变量同步。
在 x86 下的指令CMPXCHG实现了CAS,前置LOCK既可以达到原子性操作。截止2013,大部分多核处理器均支持CAS。
CAS原语有三个参数,内存地址,期望值,新值。如果内存地址的值==期望值,表示该值未修改,此时可以修改成新值。否则表示修改失败,返回false,由用户决定后续操作。
Bool CAS(T* addr, T expected, T newValue)
{
if( *addr == expected )
{
*addr = newValue;
return true;
}
else
return false;
}
ABA 问题
thread1意图对val=1进行操作变成2,cas(*val,1,2)。
thread1先读取val=1;thread1被抢占(preempted),让thread2运行。
thread2 修改val=3,又修改回1。
thread1继续执行,发现期望值与“原值”(其实被修改过了)相同,完成CAS操作。
 
使用CAS会造成ABA问题,特别是在使用指针操作一些并发数据结构时。
 
解决方案
ABAʹ:添加额外的标记用来指示是否被修改。

语言实现

Java demo
AtomicInteger atom = new AtomicInteger(1);
boolean r = atom.compareAndSet(1, 2);
 
C# demo
int i=1;
Interlocked.Increment(ref i);
 

Refs

无锁编程以及CAS的更多相关文章

  1. 4.锁--无锁编程以及CAS

    无锁编程以及CAS 无锁编程 / lock-free / 非堵塞同步 无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被堵塞的情况下实现变量的同步,所以也叫非堵塞同步(Non-b ...

  2. 【多线程】无锁编程以及CAS

    无锁编程 / lock-free / 非阻塞同步 无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步(Non-blocking Sy ...

  3. 无锁编程(四) - CAS与ABA问题

    CAS 一般采用原子级的read-modify-write原语来实现Lock-Free算法,其中LL和SC是Lock-Free理论研究领域的理想原语,但实现这些原语需要CPU指令的支持,非常遗憾的是目 ...

  4. 【Java并发编程】2、无锁编程:lock-free原理;CAS;ABA问题

    转自:http://blog.csdn.net/kangroger/article/details/47867269 定义 无锁编程是指在不使用锁的情况下,在多线程环境下实现多变量的同步.即在没有线程 ...

  5. [转]透过 Linux 内核看无锁编程

    非阻塞型同步 (Non-blocking Synchronization) 简介 如何正确有效的保护共享数据是编写并行程序必须面临的一个难题,通常的手段就是同步.同步可分为阻塞型同步(Blocking ...

  6. 海量并发的无锁编程 (lock free programming)

    最近在做在线架构的实现,在线架构和离线架构近线架构最大的区别是服务质量(SLA,Service Level Agreement,SLA 99.99代表10K的请求最多一次失败或者超时)和延时.而离线架 ...

  7. Java CAS同步机制 原理详解(为什么并发环境下的COUNT自增操作不安全): Atomic原子类底层用的不是传统意义的锁机制,而是无锁化的CAS机制,通过CAS机制保证多线程修改一个数值的安全性。

    精彩理解:  https://www.jianshu.com/p/21be831e851e ;  https://blog.csdn.net/heyutao007/article/details/19 ...

  8. C++11原子操作与无锁编程(转)

    不讲语言特性,只从工程角度出发,个人觉得C++标准委员会在C++11中对多线程库的引入是有史以来做得最人道的一件事:今天我将就C++11多线程中的atomic原子操作展开讨论:比较互斥锁,自旋锁(sp ...

  9. C++性能榨汁机之无锁编程

    C++性能榨汁机之无锁编程 来源 http://irootlee.com/juicer_lock_free/ 前言 私以为个人的技术水平应该是一个螺旋式上升的过程:先从书本去了解一个大概,然后在实践中 ...

随机推荐

  1. Oracle 的基本使用--基本命令<一>

    sql*plus 的常用命令 连接命令 1.conn[ect] 用法:conn 用户名/密码@网络服务名[as sysdba/sysoper]当用特权用户身份连接时,必须带上 as sysdba 或是 ...

  2. 组合(composition)与继承(inheritance)

    c++中一个重要的特点就是代码的重用,为了代码重用,有两个非常重要的手段,一个是继承,一个是组合 上面两种类的关系就分别是继承和组合.下面我们看一下代码示例: #ifndef USEFUL_H #de ...

  3. TCP/UDP socket

    TCP socket:有链接,绑定端口,接着去侦听,若有请求,那么accept(),获得新的socket,并且去接收/发送数据报. UDP socket:无连接,不需要侦听,也不用一个新的socket ...

  4. 文件与base64二进制转换

    /// <summary> /// 文件转换为Base64二进制流 /// </summary> /// <param name="FilePath" ...

  5. centos安装 mysql

    centos安装 mysql 1. 下载mysqlmysql被oracle收购后现在退出了企业版和社区版本,社区版本是开源的,企业版是收费的.社区版可以下载源码也可以下载二进制文件包.源码安装比较麻烦 ...

  6. 使用Process类重定向输出与错误时遇到的问题 (转)

    程序中要调用外部程序cmd.exe执行一些命令行,并取得屏幕输出,使用了Process类,基本代码如下: Process process = new Process(); process.StartI ...

  7. Incompatible operand types DeptE and int 异常处理

    Incompatible operand types DeptE and int 1.java不会运算到==的值,把==改为equals 2.java不会运算到eequals的值 把equals的改为 ...

  8. qooxdoo 3.0 发布,JavaScript 的 GUI 框架

    qooxdoo 3.0 是一个主要的版本,包含很多新特性和内部的改动,qooxdoo 3.0 是一个通用的 JS 框架,主要改进体现在 qx.Desktop, qx.Mobile, 和 qx.Webs ...

  9. mysql(或者mariadb)连接工具HeidiSQL

    Some infos around HeidiSQL Project website: http://www.heidisql.com/Google Code: http://code.google. ...

  10. mongodb(一) NoSQL简介

    NoSQL简介   写在前面,本文就是学习的记录笔记,大部分内容都属于参考,分享给大家 关系与非关系数据库      那么应该了解下影响关系数据库性能的主要原因: 在关系型数据库中,导致性能欠佳的最主 ...