`
海浪儿
  • 浏览: 273503 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

MCS锁

阅读更多

1、 为什么要引入MCS锁?

         在NUMA架构体系下,访问remote memory的速度要远远慢于访问local memory的速度。如下图所示(引自Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit):



 在前一篇文章中分析了CLH算法,由于每个线程都在其前驱线程的QNode节点的locked域自旋,在NUMA体系下,即每个线程都在其前驱线程的remote memory位置自旋,因此性能上会打折扣。

那么在NUMA体系下,如果每个线程自旋的位置都能固定在自己的local memory中,则性能相比于CLH算法,应该会有一定的提升。MCS锁就是基于这种理念设计出来的。

 

2、MCS锁介绍

       同CLH锁一样,每个申请锁的线程通过一个QNode对象表示,QNode中有一个volatile boolean类型的成员变量locked,locked为true,则表示对应的线程已经获取到了锁或者正在等待获取锁;locked为false,则表示对应的线程已经释放了锁。

       锁则由多个QNode节点组成链表标示,与CLH锁不同的是,MCS中的锁不是虚拟链表,而是实际链表,每个QNode节点都有一个next域指向其后继结点。

 

public class QNode {
	public volatile boolean locked = false;
	public QNode next = null;
}

       而链表的尾节点则通过锁AtomicReference<QNode>类型的tail成员变量指向,即tail指向加入到申请锁的队列中的最近一个线程。

 

 

public class MCSLock implements Lock {
	private AtomicReference<QNode> tail;
	private ThreadLocal<QNode> myNode;

	public MCSLock() {
		tail = new AtomicReference<QNode>(null);
		myNode = new ThreadLocal<QNode>() {
			protected QNode initialValue() {
				return new QNode();
			}
		};
	}

	public void lock() {
		QNode qnode = myNode.get();
		QNode pred = tail.getAndSet(qnode);
		if (null != pred) {
			qnode.locked = true;
			pred.next = qnode;
		}
		while (qnode.locked) {
		}
	}

	public void unlock() {
		QNode qnode = myNode.get();
		if (null == qnode.next) {
			if (tail.compareAndSet(qnode, null)) {
				return;
			}
			while (null == qnode.next) {
			}
		}
		qnode.next.locked = false;
		qnode.next = null;
	}
}

       当一个线程申请锁时:

a)首先会实例化一个QNode节点,并将其设置为自己的本地线程变量myNode;

b)然后通过调用AtomicReference的getAndSet()方法,将myNode设置为队列的最后一个节点,并返回其前驱节点

c)接着判断前面是否已经有其他线程加入到锁的等待队列中,即前驱节点是否为空。如果前驱节点为空,则说明自己是第一个加入到锁的等待队列中的线程,执行自旋,由于locked域初始值为false,所以能立即退出自旋,获取到锁;

d)如果前驱节点非空,则首先将myNode的locked域设置为true,表明自己正在等待获取锁;同时将前驱结点的next域指向myNode。

e)最后该线程一直在自己节点的locked域自旋,直到locked域变为false,即前驱节点释放了锁。

 

        当一个线程释放锁时,会处于以下三种情况之一中:

a)此刻没有其它线程正在申请锁,即当前节点的next域指向null,且tail指向当前节点:此种情况通过调用AtomicReference的compareAndSet()方法,将tail指向null;然后直接返回。

b)此刻有其他线程正在申请锁,而且已更新tail域,但还未将前驱节点的next域指向它。即当前节点的next域指向null,且tail不是指向当前节点:此种情况则一直等待其他线程设置前驱节点的next域后,才将后继节点的locked域设置为false,以便后继节点退出自旋,从而获取到释放的锁。

c)此刻有其他线程正在申请锁,而且已更新tail域,而且已将前驱节点的next域指向它。即当前节点的next域非空:此种情况则直接将后继节点的locked域设置为false,以便后继节点退出自旋,从而获取到释放的锁。

 

       下图阐述了MCS算法中锁的获取和释放过程(引自The art of Multiprocessor Programming一书):



 

  • 大小: 56.7 KB
  • 大小: 81.6 KB
1
0
分享到:
评论
1 楼 0704681032 2015-02-17  
帮助很大,谢谢!

相关推荐

    基于单片机MCS_51的智能密码锁设计

    基于MCS-51单片机的智能密码锁设计具有安全可靠、价格低廉、硬件电路简单等特点,非常适合家庭、办公室、宿舍等场所使用。此外,该设计还具备密码修改功能,使得在密码泄露的情况下也能轻松应对。通过软硬件的紧密...

    mcs51 电子密码锁

    mcs51 电子密码锁

    MCS spinlock的Linux内核模块实现.pdf

    1. MCS Spinlock 的基本原理:MCS Spinlock 是一种基于链表的自旋锁机制,每个线程都有一个自己的链表节点,当线程需要访问共享资源时,需要先申请锁,并将自己的链表节点加入到链表中。 2. MCS Spinlock 的实现:...

    字节真实面试,不多,但真实

    - **锁机制**:自旋锁、阻塞锁、乐观锁、悲观锁,以及MCS锁和CLH锁队列的应用。 - **Java线程池**:线程池的工作原理,线程数的设置考虑因素,如任务性质(计算密集型或IO密集型)。 4. **数据结构**: - **集合...

    操作系统内核实验指导书1

    2. **同步和锁**:学习原子操作、自旋锁、Ticket lock、MCS锁和读写锁的实现。 ### 第二次迭代 #### Lab 5 进程管理 深入进程创建、调度和上下文切换: 1. **创建与调度进程**:实现进程管理的基础功能。 2. **...

    学士学位论文--基于mcs51单片机电子密码锁的设计.doc

    本设计的主要目的是设计和实现基于MCS-51单片机的电子密码锁系统,该系统能够提供高安全性和便捷性,满足金融业和个人用户的需求。 一、文献综述 电子防盗锁在金融业中的应用主要集中在授予保管权和授予出入权两个...

    本科毕业设计--基于mcs51单片机电子密码锁的设计.doc

    该设计采用的MCS-51单片机作为核心单元,利用单片机串行发射、接收等功能而设计的一款具有本机开锁和报警功能的电子密码锁。 该设计的主要内容包括: 1. 设置密码及修改设置:用户可以自己修改设置6位密码,密码...

    MCS-51系列单片机Keil C语言源程序集

    7. **RTOS(实时操作系统)**:如果源程序集包含RTOS,那么会涉及到任务调度、信号量、互斥锁等概念,这对于开发复杂的多任务系统很有帮助。 通过这些源程序,你可以学习到如何编写MCS-51单片机的C语言程序,理解...

    于基mcs51单片机电子密码锁的设计--本科毕业设计.doc

    基于MCS-51单片机电子密码锁的设计 在本设计中,我们将基于MCS-51单片机设计一个电子密码锁系统,该系统主要由三个部分组成:4×4矩阵键盘接口电路、密码锁的控制电路、输出八段显示电路。该系统能够完成本机超次...

    MCS51_uCOC_II.rar_C51 printf_MCS51

    1. uCOS-II概述:uCOS-II是μC/OS-II的简称,它是一款源码公开的嵌入式实时操作系统,具有抢占式调度、任务间通信、信号量、互斥锁、事件标志组等特性。 2. MCS51兼容性:由于uCOS-II的可移植性,可以针对不同的微...

    基于mcs---51单片机电子密码锁的设计--大学毕业(论文)设计.doc

    "基于MCS-51单片机电子密码锁的设计" 本设计的主要内容是基于MCS-51单片机设计的一款电子密码锁。该系统主要由三部分组成:4×4矩阵键盘接口电路、密码锁的控制电路、输出八段显示电路。系统还配备了LED提示灯、...

    基于MCS-51的单片机应用实例

    【基于MCS-51的单片机应用实例】中涉及的...这些知识对于理解基于MCS-51的单片机如何实现数字温度计、键盘扫描、密码锁和频率计等应用至关重要。通过ADC0809,单片机可以接收和处理模拟信号,从而实现各种实用功能。

    MCS-51的智能密码锁设计

    这个不错的哦,大家需要的下前 言 随着城市建设的不断发展,高层建筑不断增多,电梯在国民经济和生活中有着广泛的应用。电梯作为高层建筑中垂直运行的交通工具已与人们的日常生活密不可分。实际上电梯是根据外部...

    移植到MCS51的uCOC_II.rar

    uCOS_II(Micro C/OS-II)是一款著名的实时操作系统(RTOS),它为嵌入式系统提供了多任务调度、信号量、互斥锁等关键功能。本文将详细介绍如何将uCOS_II移植到MCS51平台,以及这一过程中涉及的关键知识点。 一、...

    任哲老师 移植到MCS51的uCOC_II

    它提供了任务调度、信号量、互斥锁、消息队列、时间管理等丰富的内核服务,使得开发者能够更专注于应用程序的编写,而无需关心底层的实时调度问题。 移植过程通常包括以下几个关键步骤: 1. **硬件接口适配**:MCS...

    MCS单片机扩展存储器设计.ppt

    当ALE(地址锁存允许)信号上升沿到来时,P0口的地址被锁存在74LS373中,确保地址总线的稳定。 7.2节详细讨论了读写控制、地址空间分配和外部地址锁存器。在MCS-51中,读写控制涉及到对RAM、I/O接口芯片和EPROM的...

    一种Linux内核自旋锁死锁检测机制的设计与实现.pdf

    在 Linux 内核中,自旋锁的种类有很多,包括基本型、读写自旋、排队锁和 MCS 自旋锁等。每种自旋锁都有其特点和使用场景,需要根据不同的情况选择合适的自旋锁。 在设计自旋锁死锁检测机制时,需要考虑到自旋锁的...

    基于SMP的Linux内核自旋锁分析.pdf

    MCS Lock是一种基于队列的自旋锁机制,它使用一个队列来记录等待获取自旋锁的处理器。当一个处理器尝试获取自旋锁时,它将被添加到队列中,并等待前一个处理器释放自旋锁。 CLH Lock是一种基于链表的自旋锁机制,它...

    mcs-51单片机实验及实践教程

    此外,书中还包含了一些具有挑战性的项目,如电子密码锁和数字温度计,旨在锻炼读者的创新思维和综合应用能力。 总的来说,《MCS-51单片机实验及实践教程》是一本非常适合自学或课堂教学的教材,它不仅提供理论知识...

Global site tag (gtag.js) - Google Analytics