并发级别

在看多核编程相关论文时,往往一个并发算法会说自己是wait-free的或者lock-free的,或者是 non-blocking 的,这些专有词汇其实表示的是并发的程度,或者说并发的级别。并发级别的理解是阅读各种并发算法设计论文以及并发数据结构实现的必备基础。

1.1  Wait-freedom 无等待并发

Wait-freedom 指的是每一个线程都一直运行下去而无须等待外部条件,整个流程中任何操作都能在一个有限的步骤内完成,这是最高的并发级别,没有任何阻塞。

结合之前原子操作部分的知识,可以简单认为能够直接调用一个原子操作实现的算法或程序就属于Wait-free,比如下面的 increment_reference_counter 函数就是wait-free的,它封装了atomic_increment这个原子自增原语,多个线程可以同时调用这个函数对同一个内存变量进行自增,而无须任何阻塞(其实也是有阻塞的,是总线锁级别)

与此做对比,CAS类的调用就不是wait-free的,注意wait-free的原语都不能包含内部循环,CAS原语使用时通常包含在“循环直到成功”的循环内部。

void increment_reference_counter(rc_base* obj)

{

atomic_increment(obj->rc);

}

1.2  Lock-freedom 无锁并发

Lock-freedom 指的是整个系统作为一个整体一直运行下去,系统内部单个线程某段时间内可能会饥饿,这是比wait-freedom弱的并发级别,但系统整体上看依然是没有阻塞的。所有wait-free的算法显然都满足lock-free的要求。

Lock-free算法通常可以通过同步原语 CAS实现。

void stack_push(stack* s, node* n)

{

node* head;

do

{

head = s->head;

n->next = head;

}

while ( ! atomic_compare_exchange(s->head, head, n));

}

多个线程同时调用上述函数,理论上某个线程可以一直困在循环内部,但一旦有一个线程原子操作失败而返回循环,意味着有其他线程成功执行了原子操作而退出循环,从而保证系统整体是没有阻塞的。

其实前面的原子自增函数也可以用下面的原语实现,在这种实现里,不再是所有线程都无阻塞了,某些线程可能会因为CAS失败而回绕若干次循环。

void increment_reference_counter(rc_base* obj)

{

Int rc;

Do {

rc = obj->rc;

} while(!atomic_compare_exchange(obj->rc,rc,rc+1));

}

1.3  Obstruction-freedom 无阻塞并发

Obstruction-free 是指在任何时间点,一个孤立运行线程的每一个操作可以在有限步之内结束。只要没有竞争,线程就可以持续运行,一旦共享数据被修改,Obstruction-free 要求中止已经完成的部分操作,并进行回滚,obstruction-free 是并发级别更低的非阻塞并发,该算法在不出现冲突性操作的情况下提供单线程式的执行进度保证,所有 Lock-Free 的算法都是 Obstruction-free 的。

1.4  Blocking algoithms 阻塞并发

阻塞类的算法是并发级别最低的同步算法,它一般需要产生阻塞。可以简单认为基于锁的实现是blocking的算法。详细参考第五章

上述几种并发级别可以使用下图描述:

蓝色是阻塞的算法,绿色是非阻塞算法,金字塔越上方,并发级别越高,性能越好,右边的金字塔是实现工具(原子操作、锁、互斥体等)

时间: 2024-10-19 06:06:21

并发级别的相关文章

JAVA并发编程>>并发级别

理解并发 这是我在开发者头条看到的.@编程原理林振华 有目标的提升自己会事半功倍,前行的道路并不孤独. 1.阻塞 当一个线程进入临界区(公共资源区)后,其他线程必须在临界区外等待,待进去的线程执行完成任务离开临界去后,其它线程才能进去. 2.无饥饿 线程排队先来后到,不管优先级大小,先来先执行,,就不会产生饥饿等待资源,也即公平锁:相反非公平锁则是根据优先级来执行,有可能排在前面的低优先级线程被后面的高优先级插队,形成饥饿. 3.无障碍 共享资源不加锁,每个线程都可以自由读写,当监测到被其他线程

Haproxy-10万并发级别负载均衡器

Haproxy 第1章 前言 首先,我们知道nginx负载均衡集群,LVS负载均衡集群,和haproxy负载集群,这三种集群比较来说,LVS性能最好,但是搭建相对复杂,nginx的upstream模块支持集群负载,但是对web节点的健康检查功能不多,性能也没有haproxy好,这也是haproxy为什么受欢迎的原因之一! 第2章 Haproxy简介 1.      haproxy是一个使用C语言编写的开源软件,支持高可用,负载均衡,以及基于tcp和http的应用程序代理 2.      Hapr

SqlServer 并发事务(一):事务隔离级别

--查了当前数据库是事务隔离级别 DBCC USEROPTIONS 表初始内容: SELECT * FROM Test  Wherename='kk' id  name   info 1   kk      NULL [测试一:丢失更新] --事务1 begin tran select * from dbo.Test(nolock) where name = 'kk' waitfor delay '00:00:05' update T set info = 'A更改' from Test T(n

探索 ConcurrentHashMap 高并发性的实现机制

简介 ConcurrentHashMap 是 util.concurrent 包的重要成员.本文将结合 Java 内存模型,分析 JDK 源代码,探索 ConcurrentHashMap 高并发的具体实现机制. 由于 ConcurrentHashMap 的源代码实现依赖于 Java 内存模型,所以阅读本文需要读者了解 Java 内存模型.同时,ConcurrentHashMap 的源代码会涉及到散列算法和链表数据结构,所以,读者需要对散列算法和基于链表的数据结构有所了解. Java 内存模型 由

JDK的并发容器

除了提供诸如同步控制,线程池等基本工具外,为了提高开发人员的效率,JDK已经为我们准备了一大批好用的并发容器,这些容器都是线程安全的,可以大大减少开发工作量.你可以在里面找到链表.HashMap.队列等.你可以在里面找到链表.HashMap.队列等. JDK提供的这些容器大部分在java.util.con-current包中. ?ConcurrentHashMap:这是一个高效的并发HashMap.你可以理解为一个线程安全的HashMap. ?CopyOnWriteArrayList:这是一个L

SQLServer 事务的隔离级别

SQLServer事务的隔离级别 数据库是要被广大客户所共享访问的,那么在数据库操作过程中很可能出现以下几种不确定情况. 更新丢失(Lost update) 两个事务都同时更新一行数据,但是第二个事务却中途失败退出,导致对数据的两个修改都失效了.这是因为系统没有执行任何的锁操作,因此并发事务并没有被隔离开来. 脏读(Dirty Reads) 一个事务开始读取了某行数据,但是另外一个事务已经更新了此数据但没有能够及时提交.这是相当危险的,因为很可能所有的操作都被回滚. 不可重复读(Non-repe

sqlserver事务隔离级别

数据库是要被广大客户所共享访问的,那么在数据库操作过程中很可能出现以下几种不确定情况. 更新丢失(Lost update) 两个事务都同时更新一行数据,但是第二个事务却中途失败退出,导致对数据的两个修改都失效了.这是因为系统没有执行任何的锁操作,因此并发事务并没有被隔离开来. 脏读(Dirty Reads) 一个事务开始读取了某行数据,但是另外一个事务已经更新了此数据但没有能够及时提交.这是相当危险的,因为很可能所有的操作都被回滚. 不可重复读(Non-repeatable Reads) 一个事

SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因

原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中的事务概念,ACID 原则,事务中常见的问题,问题造成的原因和事务隔离级别等这些方面的知识好好的整理了一下. 其实有关 SQL Server 中的事务,说实话因为内容太多, 话题太广,稍微力度控制不好就超过了我目前知识能力范围,就不是三言两语能够讲清楚的.所以希望大家能够指出其中总结的不足之处,对我

Atitit.数据库事务隔离级别 attilax 总结

Atitit.数据库事务隔离级别 1. 事务隔离级别的作用 1 2. 在的隔离级别 2 3. 常见数据库的默认管理级别 3 1. 事务隔离级别的作用 较低的隔离级别可以增强许多用户同时访问数据的能力,但也增加了用户可能遇到的并发副作用(例如脏读或丢失更新)的数量.相反,较高的隔离级别减少了用户 可能遇到的并发副作用的类型,但需要更多的系统资源,并增加了一个事务阻塞其他事务的可能性.应平衡应用程序的数据完整性要求与每个隔离级别的开销,在此 基础上选择相应的隔离级别.最高隔离级别(可序列化)保证事务