一。引文
1.1 SMP(Symmetric Multi-Processor)
对称多处理器结构,指服务器中多个CPU对称工作,每个CPU访问内存地址所需时间相同。其主要特征是共享,包含对CPU,内存,I/O等进行共享。
SMP能够保证内存一致性,但这些共享的资源很可能成为性能瓶颈,随着CPU数量的增加,每个CPU都要访问相同的内存资源,可能导致内存访问冲突,
可能会导致CPU资源的浪费。常用的PC机就属于这种。
1.2 NUMA(Non-Uniform Memory Access)
非一致存储访问,将CPU分为CPU模块,每个CPU模块由多个CPU组成,并且具有独立的本地内存、I/O槽口等,模块之间可以通过互联模块相互访问,
访问本地内存的速度将远远高于访问远地内存(系统内其它节点的内存)的速度,这也是非一致存储访问的由来。NUMA较好地解决SMP的扩展问题,
当CPU数量增加时,因为访问远地内存的延时远远超过本地内存,系统性能无法线性增加。
二。CLH
CLH(Craig, Landin, and Hagersten locks): 是一个自旋锁,能确保无饥饿性,提供先来先服务的公平性。
CLH锁也是一种基于链表的可扩展、高性能、公平的自旋锁,申请线程只在本地变量上自旋,它不断轮询前驱的状态,如果发现前驱释放了锁就结束自旋。
当一个线程需要获取锁时:
1.创建一个的QNode,将其中的locked设置为true表示需要获取锁
2.线程对tail域调用getAndSet方法,使自己成为队列的尾部,同时获取一个指向其前趋结点的引用myPred
3.该线程就在前趋结点的locked字段上旋转,直到前趋结点释放锁
4.当一个线程需要释放锁时,将当前结点的locked域设置为false,同时回收前趋结点
如下图,线程A需要获取锁,其myNode域为true,tail指向线程A的结点,然后线程B也加入到线程A后面,tail指向线程B的结点。然后线程A和B
都在其myPred域上旋转,一旦它的myPred结点的locked字段变为false,它就可以获取锁。明显线程A的myPred locked域为false,此时线程A获取
到了锁。
三。CLH代码示例
public class CLHLock implements Lock { AtomicReference<QNode> tail ; ThreadLocal<QNode> myPred; ThreadLocal<QNode> myNode; public CLHLock() { tail = new AtomicReference<QNode>(new QNode()); myNode = new ThreadLocal<QNode>() { protected QNode initialValue() { return new QNode(); } }; myPred = new ThreadLocal<QNode>() { protected QNode initialValue() { return null; } }; } @Override public void lock() { QNode qnode = myNode.get(); qnode.locked = true; QNode pred = tail.getAndSet(qnode); myPred.set(pred); while (pred.locked) { } } @Override public void unlock() { QNode qnode = myNode.get(); qnode.locked = false; myNode.set(myPred.get()); } }
四。CLH分析
CLH队列锁的优点是空间复杂度低(如果有n个线程,L个锁,每个线程每次只获取一个锁,那么需要的存储空间是O(L+n),n个线程有n个
myNode,L个锁有L个tail),CLH的一种变体被应用在了JAVA并发框架中(AbstractQueuedSynchronizer.Node)。CLH在SMP系统结构下
该法是非常有效的。但在NUMA系统结构下,每个线程有自己的内存,如果前趋结点的内存位置比较远,自旋判断前趋结点的locked域,性能
将大打折扣,一种解决NUMA系统结构的思路是MCS队列锁。
五。MCS
MSC与CLH最大的不同并不是链表是显示还是隐式,而是线程自旋的规则不同:CLH是在前趋结点的locked域上自旋等待,而MCS是在自己的
结点的locked域上自旋等待。正因为如此,它解决了CLH在NUMA系统架构中获取locked域状态内存过远的问题。
MCS队列锁的具体实现如下:
a. 队列初始化时没有结点,tail=null
b. 线程A想要获取锁,于是将自己置于队尾,由于它是第一个结点,它的locked域为false
c. 线程B和C相继加入队列,a->next=b,b->next=c。且B和C现在没有获取锁,处于等待状态,所以它们的locked域为true,
尾指针指向线程C对应的结点
d. 线程A释放锁后,顺着它的next指针找到了线程B,并把B的locked域设置为false。这一动作会触发线程B获取锁
六。代码实现
public class MCSLock implements Lock { AtomicReference<QNode> tail; ThreadLocal<QNode> myNode; @Override public void lock() { tail = new AtomicReference<QNode>(new QNode()); QNode qnode = myNode.get(); QNode pred = tail.getAndSet(qnode); if (pred != null) { qnode.locked = true; pred.next = qnode; // wait until predecessor gives up the lock while (qnode.locked) { } } } @Override public void unlock() { QNode qnode = myNode.get(); if (qnode.next == null) { if (tail.compareAndSet(qnode, null)) return; // wait until predecessor fills in its next field while (qnode.next == null) { } } qnode.next.locked = false; qnode.next = null; } class QNode { boolean locked = false; QNode next = null; } }
相关推荐
C语言高级编程技术(CLH)C语言高级编程技术(CLH)C语言高级编程技术(CLH)C语言高级编程技术(CLH)C语言高级编程技术(CLH)C语言高级编程技术(CLH)C语言高级编程技术(CLH)C语言高级编程技术(CLH)C语言高级编程技术(CLH)...
C语言也能做大事1笔记(CLH)C语言也能做大事1笔记(CLH)C语言也能做大事1笔记(CLH)C语言也能做大事1笔记(CLH)C语言也能做大事1笔记(CLH)C语言也能做大事1笔记(CLH)C语言也能做大事1笔记(CLH)C语言也能做大事1笔记(CLH)...
为了实现自旋锁,Linux内核使用了多种技术,包括Ticket Lock、MCS Lock和CLH Lock等。 Ticket Lock是一种简单的自旋锁机制,它使用一个 ticket 变量来记录当前获取自旋锁的处理器的ID。当一个处理器尝试获取自旋锁...
windows编程模型(CLH)windows编程模型(CLH)windows编程模型(CLH)windows编程模型(CLH)windows编程模型(CLH)windows编程模型(CLH)windows编程模型(CLH)windows编程模型(CLH)windows编程模型(CLH)windows编程...
【新手乐园笔记(CLH)】是一份专为IT初学者设计的学习资料,旨在帮助新手快速熟悉并掌握计算机基础知识和常见技术。这份笔记涵盖了多个重要领域,包括但不限于操作系统、网络基础、编程语言入门、数据结构与算法、...
c与c++嵌入式系统编程(CLH)c与c++嵌入式系统编程(CLH)c与c++嵌入式系统编程(CLH)c与c++嵌入式系统编程(CLH)c与c++嵌入式系统编程(CLH)c与c++嵌入式系统编程(CLH)c与c++嵌入式系统编程(CLH)c与c++嵌入式系统编程(CLH)...
【CLH 报告——李春华 LEADER 工作汇报】 李春华作为DB的LEADER,其工作职责和管理活动主要集中在三个方面:管理、组织程序和工作指导。他需要密切关注人力配置,如人员调动、代班和离职情况,确保班组内部的人力...
`code`文件可能会包含CLHLock的源代码,你可以研究其如何通过节点间的交互来实现自旋等待和锁的释放。 4. **MCSLock(Mellor-Crummey and Scott Lock)**:与CLHLock类似,也是一种链表型自旋锁。MCSLock使用单向...
windows 编程基础(CLH)windows 编程基础(CLH)windows 编程基础(CLH)windows 编程基础(CLH)windows 编程基础(CLH)windows 编程基础(CLH)windows 编程基础(CLH)windows 编程基础(CLH)windows 编程基础(CLH)
C语言课程设计案例精编(CLH)C语言课程设计案例精编(CLH)C语言课程设计案例精编(CLH)C语言课程设计案例精编(CLH)C语言课程设计案例精编(CLH)C语言课程设计案例精编(CLH)C语言课程设计案例精编(CLH)C语言课程设计案例...
windows API 每日一练(CLH)windows API 每日一练(CLH)windows API 每日一练(CLH)windows API 每日一练(CLH)windows API 每日一练(CLH)windows API 每日一练(CLH)windows API 每日一练(CLH)windows API...
C语言鼠标操作方法及源码(CLH)C语言鼠标操作方法及源码(CLH)C语言鼠标操作方法及源码(CLH)C语言鼠标操作方法及源码(CLH)C语言鼠标操作方法及源码(CLH)C语言鼠标操作方法及源码(CLH)C语言鼠标操作方法及源码(CLH)...
《the c programming language》(CLH)《the c programming language》(CLH)《the c programming language》(CLH)《the c programming language》(CLH)《the c programming language》(CLH)《the c programming ...
课程详细讨论了不同的锁机制,如TAS锁、TTAS锁、回退锁、队列锁(CLH队列锁和MCS队列锁)以及超时锁。此外,还涉及了管程和阻塞同步,以及读-写锁、可重入锁和信号量等同步机制在链表操作中的应用。 并发数据结构是...
CLH锁利用了线程局部变量和原子更新操作来实现线程间的同步,当一个线程想要获取锁时,它会创建一个节点并加入链表,然后调用`park()`进入等待状态,直到前驱节点释放锁并唤醒它。 阻塞锁的优势在于,被阻塞的线程...
【VB教程_CLH】是一个关于Visual Basic(VB)学习资源的集合,主要涵盖了VB的基础知识以及数据库编程的应用。在这个压缩包中,用户可以找到一系列帮助理解并掌握VB编程的资料,包括可能的教程文档、示例代码、数据库...
《Fastcopy_clh:高效能的拷贝利器详解》 Fastcopy_clh是一款备受赞誉的文件复制工具,尤其在IT行业内被广泛使用。其高效、稳定的特点,使其在大量数据拷贝任务中表现出色,成为了许多系统管理员和普通用户的首选。...
总结,ReentrantLock通过AQS和CLH队列实现了一种灵活且高效的锁机制,既支持公平锁又支持非公平锁,同时具备可重入、中断和超时等待的能力。理解和掌握ReentrantLock的工作原理对于编写高并发、高性能的Java程序至关...
环保行业报告:国际环保巨头-CLH-时势造英雄,这份资料详尽地剖析了全球环保领域的领军企业CLH及其在当前环境挑战中的角色。报告涵盖了30个页面,深入探讨了环保行业的现状、发展趋势以及CLH如何利用时势成为行业的...
3. CLHLock(Craig, Landin, and Hagersten Lock)和MCSLock(Mellor-Crummey and Scott Lock):这两种自旋锁是基于链表结构的公平锁,它们将等待线程组织成一个队列,并使用`AtomicReferenceFieldUpdater`等原子...