zoukankan      html  css  js  c++  java
  • Atitit 锁的不同层级 app锁 vm锁 os锁 硬件锁 目录 1. 在硬件层面,CPU提供了原子操作、关中断、锁内存总线的机制 1 1.1. test and set指令 1 1.2. 锁内

    Atitit 锁的不同层级 app锁 vm锁 os锁 硬件锁

     

     

    目录

    1. 在硬件层面,CPU提供了原子操作、关中断、锁内存总线的机制 1

    1.1. test and set指令 1

    1.2. 锁内存总线 1

    1.3. Cas 原子操作 2

    2. Os的锁 2

    2.1. mutex(互斥锁)、 2

    2.2. 原子操作、信号量(semaphore)、 3

    2.3. 自旋锁spin_lock 3

    2.4. BKL(Big Kernel Lock) 3

    2.5. 顺序锁 3

    3. Vm的锁 4

    3.1. monitor锁 调用os锁 4

    3.2. 可以使用队列实现锁 纯软件锁 4

    4. 3. 硬件上怎么实现的 4

     

    1. 在硬件层面,CPU提供了原子操作、关中断、锁内存总线的机制
      1. test and set指令

    既然只有中断才能把上锁过程打断,造成多线程操作失败。我先关中断不就得了,在加锁操作完成后再开中断。
    2、上面这个手段太笨重了,能不能硬件做一种加锁的原子操作呢?能,大名鼎鼎的“test and set”指令就是做这个事情的。(怎么,test and set是干什么的?同学,看来你上课时不够专心啊,赶紧回头复习复习)

     

      1. 锁内存总线



    通过上面的手段,单核环境下,锁的实现问题得到了圆满的解决。那么多核环境呢?简单嘛,还是“test and set”不就得了,这是一条指令,原子的,不会有问题的。真的吗,单独一条指令能够保证该指令在单个核上执行过程中不会被中断打断,但是两个核同时执行这个指令呢?。。。我再想想,硬件执行时还是得从内存中读取lock,判断并设置状态到内存,貌似这个过程也不是那么原子嘛。对,多个核执行确实会存在这个问题。怎么办呢?首先我们得明白这个地方的关键点,关键点是两个核会并行操作内存而且从操作内存这个调度来看“test and set”不是原子的,需要先读内存然后再写内存,如果我们保证这个内存操作是原子的,就能保证锁的正确性了。确实,硬件提供了锁内存总线的机制,我们在锁内存总线的状态下执行test and set操作,就能保证同时只有一个核来test and set,从而避免了多核下发生的问题。

     

      1. Cas 原子操作

     

    1. Os的锁

     

    在硬件层面,CPU提供了原子操作、关中断、锁内存总线的机制;OS基于这几个CPU硬件机制,就能够实现锁;再基于锁,就能够实现各种各样的同步机制(信号量、消息、Barrier等等等等)。所以要想理解OS的各种同步手段,首先需要理解本文介绍的内容,这时最原点的机制,所有的OS上层同步手段都基于此。

     

    在基于锁,就能实现各种各样的同步机制(信号量、消息等等)

      1. mutex(互斥锁)、

     互斥锁主要用于实现内核中的互斥访问功能。内核互斥锁是在原子API之上实现的,但这对于内核用户是不可见的。对它的访问必须遵循一些规则:同一时间只能有一个任务持有互斥锁,而且只有这个任务可以对互斥锁进行解锁。互斥锁不能进行递归锁定或解锁。一个互斥锁对象必须通过其API初始化,而不能使用memset或复制初始化。一个任务在持有互斥锁的时候是不能结束的。互斥锁所使用的内存区域是不能被释放的。使用中的互斥锁是不能被重新初始化的。并且互斥锁不能用于中断上下文。但是互斥锁比当前的内核信号量选项更快,并且更加紧凑,因此如果它们满足您的需求,那么它们将是您明智的选择。

      1. 原子操作、信号量(semaphore)、

    读写信号量(rw_semaphore)、spinlock

      1. 自旋锁spin_lock
      2. BKL(Big Kernel Lock)

    BKL即全局内核锁,也称大内核锁,它是一个全局自旋锁。

     

      1. 顺序锁

      顺序锁为写者赋予更高的优先级,写者永远不会等待读者。缺点是读者有时不得不读多次数据以获取正确的结果。

      顺序锁的数据结构中除了有spinlock外,还有一个顺序号。如果成功获得锁,顺序锁的顺序号会加1,以便读者能够检查出是否在读期间有写者访问过。读者在读取数据前后两次读顺序值,如果两次值不相同,则说明读取期间有新的写者操作过数据了,那么本次读取就是无效的。

     

    1. Vm的锁
      1. monitor锁 调用os锁
      2. 可以使用队列实现锁 纯软件锁

    Free的队列,基本思路是自旋后阻塞,竞争切换后继续竞争锁,稍微牺牲了公平性,但获得了高吞吐量。

     

    1. 3. 硬件上怎么实现的

           前面提到,cpu会通过对总线加锁的手段来解决多核同时获取锁的情况,它到时是怎么实现的呢? 在cpu芯片上有一个HLOCK Pin,可以通过发送指令来操作,将#HLOCK Pin电位拉低,并持续到这条指令执行完毕,从而将总线锁住,这样同一总线上的其他CPU就不能通过总线来访问内存了。最开始这些功能是用来测试cpu的,后来被操作系统实现而封装成各种功能:关键代码段,信号量等。

     

    Ref

    linux内核锁机制 - 全文 - 嵌入式操作系统 - 电子发烧友网

  • 相关阅读:
    C# 任务、线程、同步(五)
    C# 任务、线程、同步(四)
    C# 得到本周的第一天和最后一天
    C# Datatable 转实体对象
    C# 任务、线程、同步(三)
    apache的工作模式 和 最大连接数设置
    MySQL中的配置参数interactive_timeout和wait_timeout(可能导致过多sleep进程的两个参数)
    上传图片到另外的服务器
    Brackets
    centos 安装mysql 5.5.12
  • 原文地址:https://www.cnblogs.com/attilax/p/15197068.html
Copyright © 2011-2022 走看看