lock free(无锁并发)是什么
一、非阻塞同步(Non-blocking Synchronization)
1. 无锁编程 / lock-free / 非阻塞同步
无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步(Non-blocking Synchronization)。
实现非阻塞同步的方案称为“无锁编程算法”( Non-blocking algorithm)。
lock-free是目前最常见的无锁编程的实现级别(一共三种级别):
- wait-free
- lock-free
- obstruction-free
2. 为什么要 Non-blocking sync ?
使用lock实现线程同步有很多缺点:
* 产生竞争时,线程被阻塞等待,无法做到线程实时响应。
* dead lock。
* live lock。
* 优先级翻转。
* 使用不当,造成性能下降。
3. wait-free
是最理想的模式,整个操作保证每个线程在有限步骤下完成。
保证系统级吞吐(system-wide throughput)以及无线程饥饿。
截止2011年,没有多少具体的实现。即使实现了,也需要依赖于具体CPU。
4. lock-free
允许个别线程饥饿,但保证系统级吞吐。
确保至少有一个线程能够继续执行。
wait-free的算法必定也是lock-free的。
5. obstruction-free
在任何时间点,一个线程被隔离为一个事务进行执行(其他线程suspended),并且在有限步骤内完成。
在执行过程中,一旦发现数据被修改(采用时间戳、版本号),则回滚。
也叫做乐观锁,即乐观并发控制(OOC)。
事务的过程是:1读取,并写时间戳;2准备写入,版本校验;3校验通过则写入,校验不通过,则回滚。
二、CAS
CAS( compare and swap) 原子操作,用来实现多线程下的变量同步。
保证了如果需要更新的地址没有被其他进程(线程)改动过,那么它可以安全的写入。
而这也是我们对于某个数据或者数据结构加锁要保护的内容,保证读写的一致性,不出现dirty data。
CAS原语有三个参数:
- 内存地址,
- 期望值,
- 新值。
算法逻辑:
- 如果内存地址的值==期望值,表示该值未修改,此时可以修改成新值。
- 否则表示修改失败,返回false,由用户决定后续操作。
int compare_and_swap (int* reg, int oldval, int newval) {
ATOMIC();
int old_reg_val = *reg;
if (old_reg_val == oldval)
*reg = newval;
END_ATOMIC();
return old_reg_val;
}
可在循环中不断执行CAS,如果共享变量没有改变,那么swap,在当前环境中写入,否则继续do-while的Retry-Loop。
三、ABA问题
ABA问题最容易发生在lock free算法中的,地址被重用的情况。
无锁相当于“锁”的粒度变小了,主要是“锁”HEAD和TAIL这两个关键资源。而不是整个数据结构。
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);
lock free(无锁并发)是什么的更多相关文章
- Lock Free (无锁并发)
CAS( compare and swap) 原子操作,保证了如果需要更新的地址没有被其他进程(线程)改动过,那么它可以安全的写入.而这也是我们对于某个数据或者数据结构加锁要保护的内容,保证读写的一致 ...
- 无锁并发框架Disruptor学习入门
刚刚听说disruptor,大概理一下,只为方便自己理解,文末是一些自己认为比较好的博文,如果有需要的同学可以参考. 本文目标:快速了解Disruptor是什么,主要概念,怎么用 1.Disrupto ...
- 加锁并发算法 vs 无锁并发算法
Heinz Kabutz 在上周举办了一次成功 JCrete研讨会,我在会上参加了对一种新的 StampedLock(于JSR166中 引入) 进行的评审.StampedLock (邮戳锁) 旨在解决 ...
- Nah Lock: 一个无锁的内存分配器
概述 我实现了两个完全无锁的内存分配器:_nalloc 和 nalloc. 我用benchmark工具对它们进行了一组综合性测试,并比较了它们的指标值. 与libc(glibc malloc)相比, ...
- paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象)
paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象) 1 锁的缺点 2 CAS(Compare ...
- 使用CAS实现无锁的SkipList
无锁 并发环境下最常用的同步手段是互斥锁和读写锁,例如pthread_mutex和pthread_readwrite_lock,常用的范式为: void ConcurrencyOperation() ...
- linux内核无锁缓冲队列kfifo原理
Linux kernel里面从来就不缺少简洁,优雅和高效的代码 比如,通过限定写入的数据不能溢出和内存屏障实现在单线程写单线程读的情况下不使用锁.因为锁是使用在共享资源可能存在冲突的情况下.还用设置b ...
- 海量并发的无锁编程 (lock free programming)
最近在做在线架构的实现,在线架构和离线架构近线架构最大的区别是服务质量(SLA,Service Level Agreement,SLA 99.99代表10K的请求最多一次失败或者超时)和延时.而离线架 ...
- 基于无锁的C#并发队列实现(转载)
最近开始学习无锁编程,和传统的基于Lock的算法相比,无锁编程具有其独特的优点,Angel Lucifer的关于无锁编程一文对此有详细的描述. 无锁编程的目标是在不使用Lock的前提下保证并发过程中共 ...
随机推荐
- Cisco WS-C4503-E CPU使用率高问题排查
现状描述: 办公网环境下由2台VSS模式下WS-C4503-E 作为核心交换机,下接若干台WS-C2960X-48LPS-L作为接入.行政同事在进行工位改造的时候为方便将原工位网线下联若干台hub. ...
- cassandra权威指南读书笔记--客户端
DataStax驱动最成熟.默认,驱动程序会使用第一个连接的节点作为支持的版本协议.如果集群存在高低版本的节点(比如升级场景),如果驱动先连接不同不同版本的节点,可能会出现不兼容.驱动支持压缩客户端和 ...
- Flink-v1.12官方网站翻译-P015-Glossary
术语表 Flink Application Cluster Flink应用集群是一个专用的Flink集群,它只执行一个Flink应用的Flink作业.Flink集群的寿命与Flink应用的寿命绑定. ...
- CENTOS7 使用YUM安装MARIADB
现在在服务器配置数据库,一般都会直接配置MariaDB,它可以实现mysql数据库连接. 1.安装MariaDB 安装命令 yum -y install mariadb mariadb-server ...
- Codeforces Round #677 (Div. 3) G. Reducing Delivery Cost(dijkstra算法)
题目链接:https://codeforces.com/contest/1433/problem/G 题解 跑 \(n\) 遍 \(dijkstra\) 得到任意两点间的距离,然后枚举哪一条边权为 \ ...
- Codeforces Round #668 (Div. 2)【ABCD】
比赛链接:https://codeforces.com/contest/1405 A. Permutation Forgery 题意 给出一个大小为 $n$ 的排列 $p$,定义 \begin{equ ...
- Linux-输出/输入重定向
目录 重定向的分类 输出重定向 将标准输出重定向到文件 将标准输出追加重定向到文件 将错误输出重定向到文件 将标准输出和错误输出都重定向到文件 将错误输出重定向到黑洞文件 输入重定向 重定向的分类 名 ...
- Redis 持久化(Persistence)
作为内存数据库,Redis 依然提供了持久化机制,其主要目的有两个: 安全:保证进程崩溃后数据不会丢失 备份:方便数据迁移与快速恢复 Redis 同时提供两种持久化机制: RDB 快照:数据库在某个时 ...
- 一句话木马的简单例子 网站webshell & 远程连接
一 概述 本地 kail linux 目标 windows nt 服务器 二 过程 首先编写一句话木马 index.php 一句话木马的原理就是把C=xxx 字符串当成php语句执行 注意这里用 ...
- Python import本地模块
无法识别本地模块 在pycharm中选择文件夹Mark Directory as -> Source root. 或者使用sys.path.append()添加文件夹路径 还是报错ImportE ...