常见锁相关

2023-11-18

Linux 锁

  • futex: 所有的futex同步操作都应该从用户空间开始,首先创建一个futex同步变量,也就是位于共享内存的一个整型计数器。当进程尝试持有锁或者要进入互斥区的时候,对futex执行"down"操作,即原子性的给futex同步变量减1。如果同步变量变为0,则没有竞争发生, 进程照常执行。如果同步变量是个负数,则意味着有竞争发生,需要调用futex系统调用的futex_wait操作休眠当前进程。sys_futex系统调用进入kernel mode进行处理 用来挂起或者唤醒进程来挂起或者唤醒进程,当然这部分工作也只能在内核态下完成。当进程释放锁或 者要离开互斥区的时候,对futex进行"up"操作,即原子性的给futex同步变量加1。如果同步变量由0变成1,则没有竞争发生,进程照常执行。如 果加之前同步变量是负数,则意味着有竞争发生,需要调用futex系统调用的futex_wake操作唤醒一个或者多个等待进程。这里的原子性加减通常是用CAS(Compare and Swap)完成的,与平台相关。可见: futex是从用户态开始,由用户态和核心态协调完成的。pthread_mutex_lock()是一个用户空间API,在C库中实现。在Linux上,它通常基于内核futex()系统调用。

    通常有两种处理方式:一种是没有获取到锁的线程就一直循环等待判断该资源是否已经释放锁,这种锁叫做自旋锁,它不用将线程阻塞起来(NON-BLOCKING);还有一种处理方式就是把自己阻塞起来,等待重新调度请求,这种叫做互斥锁。两者各有利弊,已加锁时阻塞掉当前线程让出cpu资源可以去执行别的线程,通过减少cpu的浪费来提高效率,但是这个过程需要进行上下文切换,保存各寄存器状态需要花费时间,如果每个线程对于锁的占有时间很短,拥有锁之后会很快释放锁,那么自旋锁又更加高效,所以要根据具体情况具体使用。

  • 互斥锁:在无法得到资源时,内核线程会进入睡眠阻塞状态,这需要陷入内核进行cpu上下文的切换。而自旋锁处于忙等待状态。因此,如果资源被占用的时间较长,使用互斥锁较好,因为可让CPU调度去做其它进程的工作。

  • 自旋锁: 自旋锁的原理比较简单,如果持有锁的线程能在短时间内释放锁资源,那么那些等待竞争锁的线程就不需要做内核态和用户态之间的切换进入阻塞状态,它们只需要等一等(自旋),等到持有锁的线程释放锁之后即可获取,这样就避免了用户进程和内核切换的消耗。因为自旋锁避免了操作系统进程调度和线程切换,所以自旋锁通常适用在时间比较短的情况下。由于这个原因,操作系统的内核经常使用自旋锁。但是,如果长时间上锁的话,自旋锁会非常耗费性能,它阻止了其他线程的运行和调度。线程持有锁的时间越长,则持有该锁的线程将被 OS(Operating System) 调度程序中断的风险越大。如果发生中断情况,那么其他线程将保持旋转状态(反复尝试获取锁),而持有该锁的线程并不打算释放锁,这样导致的是结果是无限期推迟,直到持有锁的线程可以完成并释放它为止。解决上面这种情况一个很好的方式是给自旋锁设定一个自旋时间,等时间一到立即释放自旋锁。自旋锁的目的是占着CPU资源不进行释放,等到获取锁立即进行处理。但是如何去选择自旋时间呢?如果自旋执行时间太长,会有大量的线程处于自旋状态占用 CPU 资源,进而会影响整体系统的性能。因此自旋的周期选的额外重要!JDK在1.6 引入了适应性自旋锁,适应性自旋锁意味着自旋时间不是固定的了,而是由前一次在同一个锁上的自旋时间以及锁拥有的状态来决定,基本认为一个线程上下文切换的时间是最佳的一个时间。自旋锁只能用于多核cpu,如果是单核将无限制处于自旋状态。

    单cpu自旋锁:运行在临界区域代码时,不运行发生进程切换(即不能阻塞,相当于主动释放cpu),要独占cpu。
    多cpu自旋锁:运行在临界区域代码时,没加锁的cpu发生进程切换,加锁的不行。
    自旋锁是指当一个线程尝试获取某个锁时,如果该锁已被其他线程占用,就一直循环检测锁是否被释放,而不是进入线程挂起或睡眠状态。

    自旋锁和互斥锁区别: 自旋锁是一种互斥锁的实现方式而已,相比一般的互斥锁会在等待期间放弃cpu,自旋锁(spinlock)则是不断循环并测试锁的状态,这样就一直占着cpu。互斥锁:用于保护临界区,确保同一时间只有一个线程访问数据。对共享资源的访问,先对互斥量进行加锁,如果互斥量已经上锁,调用线程会阻塞,直到互斥量被解锁。在完成了对共享资源的访问后,要对互斥量进行解锁。

数据库锁

当程序中可能出现并发的情况时,我们就需要通过一定的手段来保证在并发情况下数据的准确性,通过这种手段保证了当用户和其他用户一起操作时,所得到的结果和他单独操作时的祷告的结果是一样的。这种手段就叫做并发控制。并发控制的目的是保证一个用户的工作不会对另一个用户的工作产生不合理的影响。没有做好并发控制,就可能导致脏读、幻读和不可重复读等问题。实现并发控制的主要手段大致可以分为乐观并发控制和悲观并发控制两种。

  • 悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

    悲观锁主要分为共享锁或排他锁

    1. 共享锁【Shared lock】又称为读锁,简称S锁。顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。锁级别:Row Lock 行级别。
    2. 排他锁【Exclusive lock】又称为写锁、独占锁,简称X锁。顾名思义,排他锁就是不能与其他锁并存,如果一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据行读取和修改。数据库的增删改操作默认都会加排他锁,而查询不会加任何锁。锁级别:Row Lock 行级别。
  • 乐观锁: 总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,如果更新了这个数据,放弃操作,否则执行操作。可以使用版本号机制和CAS(compare and swap)(比较与交换)算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量。乐观锁适用于多读的应用类型,这样可以提高吞吐量

    应用: 使用数据版本(Version)记录机制实现,这是乐观锁最常用的一种实现方式。何谓数据版本?即为数据增加一个版本标识,一般是通过为数据库表增加一个数字类型的 “version” 字段来实现。当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一。当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比对,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数据。

  • 表锁: 锁表,开销小,加锁快;不会出现死锁;锁定力度大,发生锁冲突概率高,并发度最低

  • 行锁: 锁行,开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高。

死锁

  • 概念:死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其它进程所占用不会释放的资源而处于的一种永久等待状态。

  • 产生死锁的四个必要条件

    1.互斥性:线程对资源的占有是排他性的,一个资源只能被一个线程占有,直到释放。

    2.占用并保持:一个线程对请求被占有资源发生阻塞时,对已经获得的资源不释放。

    3.非抢占:一个线程在释放资源之前,其他的线程无法抢占占用。

    4.循环等待:发生死锁时,线程进入死循环,永久阻塞。

  • 死锁的解除
      1.抢占资源,从一个或多个进程中抢占足够数量的资源,分配给死锁进程,以解除死锁状态。
      2.终止(或撤销)进程,终止(或撤销)系统中的一个或多个死锁进程,直至打破循环环路,使系统从死锁状态解脱出来。

  • 产生死锁的原因
    1.竞争不可抢占性资源: p1已经打开F1,想去打开F2,p2已经打开F2,想去打开F1,但是F1和F2都是不可抢占的,这是发生死锁。
    2.竞争可消耗资源引起死锁: 进程间通信,如果顺序不当,会产生死锁,比如p1发消息m1给p2,p1接收p3的消息m3,p2接收p1的m1,发m2给p3,p3,以此类推,如果进程之间是先发信息的那么可以完成通信,但是如果是先接收信息就会产生死锁。
    3.进程推进顺序不当: 进程在运行过程中,请求和释放资源的顺序不当,也同样会导致产生进程死锁。

  • 避免死锁的方法
    银行家算法(Banker’s Algorithm)是一个避免死锁(Deadlock)的著名算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生的算法。它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。
      在银行中,客户申请贷款的数量是有限的,每个客户在第一次申请贷款时要声明完成该项目所需的最大资金量,在满足所有贷款要求时,客户应及时归还。银行家在客户申请的贷款数量不超过自己拥有的最大值时,都应尽量满足客户的需要。在这样的描述中,银行家就好比操作系统,资金就是资源,客户就相当于要申请资源的进程。
      银行家算法是一种最有代表性的避免死锁的算法。在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。为实现银行家算法,系统必须设置若干数据结构。

1.破坏“占用并保持”条件

想办法,让进程不要那么贪心,自己已经有了资源就不要去竞争那些不可抢占的资源。比如,让进程在申请资源时,一次性申请所有需要用到的资源,不要一次一次来申请,当申请的资源有一些没空,那就让线程等待。不过这个方法比较浪费资源,进程可能经常处于饥饿状态。还有一种方法是,要求进程在申请资源前,要释放自己拥有的资源。

2.破坏“不可抢占”条件

允许进程进行抢占,方法一:如果去抢资源,被拒绝,就释放自己的资源。方法二:操作系统允许抢,只要你优先级大,可以抢到。

3.破坏“循环等待”条件

将系统中的所有资源统一编号,进程可在任何时刻提出资源申请,但所有申请必须按照资源的编号顺序(升序)提出

  • 死锁的检测
    1.每个进程、每个资源制定唯一编号
    2.设定一张资源分配表,记录各进程与占用资源之间的关系
    3.设置一张进程等待表,记录各进程与要申请资源之间的关系
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

常见锁相关 的相关文章

  • Minikube 架构及启动流程剖析

    原文作者 wzqnls 编辑 夏天 对于要学习 Kubernetes 或者需要本地开发的开发人员来说 Minikube 是一个不错的选择 通过使用 Minikube 这个工具 我们可以非常快捷地在本地部署一套单节点的 Kubernetes
  • Linux系统的安装(在VM虚拟机上安装CentOS 7)

    工具准备 物理计算机一台 配置要求 操作系统 win10 64位 大家基本上都是 硬盘可用容量 20G以上 内存容量 4G以上 虚拟机安装包 VMware workstation full 12 5 下载链接 点我下载 提取码 9gha C
  • RTX线程通信之——线程标志

    文章目录 Thread Flags 概念 RTX线程标志API 案例 LED灯同步闪亮 小结 参考资料 Thread Flags In a real application we need to be able to communicate
  • Client-Server问题

    1 实验内容与要求 需要创建客户Client和服务器Server两个进程 它们通过管道进行通信 Client进程派生3个生产者线程 一个管道线程 共享一个20个slots的缓冲区 每个生产者线程随机产生一个数据 打印出来自己的id 进程 线
  • ps aux 和ps -aux和 ps -ef的选择

    Linux中的ps命令是Process Status的缩写 ps命令用来列出系统中当前运行的那些进程 ps命令列出的是当前那些进程的快照 就是执行ps命令的那个时刻的那些进程 如果想要动态的显示进程信息 就可以使用top命令 要对进程进行监
  • 设备管理过程

    复杂度2 5 机密度2 5 最后更新2021 04 19 AIX中对设备会有如下五个操作 define aix下能看到设备的定义 但驱动程序并没有加载或初始化 该设备不可用 lsdev看到设备时defined 很多逻辑设备 vg lv等 只
  • 安装黑苹果双系统专辑贴(持续更新...)

    最近终于开始研究黑苹果 然后浏览了几篇文章贴收集一下 以便需要时随时阅览 和同学们互相学习 零基础篇 1 https blog csdn net a792396951 article details 80230946 2 https zhu
  • Linux,Network manager 导致节点异常重启

    推断是Network manager 导致的 原因待查今天在VmWare的虚拟机上装了个测试RAC 又遇到了一个摸不到头绪的问题CRS装好后 一旦登陆图形界面 节点就重启 事情就有这么巧不登陆图形界面 观察了1个小时没问题 一旦登陆后 立刻
  • 程序员的自我修养——链接、装载与库

    1 温故而知新 操作系统概念 北桥 连接高速芯片 系统调用接口 以软件中断的方式提供 如Linux使用0x80号中断作为系统调用接口 多任务系统 进程隔离 设备驱动 直接使用物理内存的弊端 地址空间不隔离 内存使用效率低 程序运行的地址不确
  • Elasticsearch 日志

    下载并安装 Filebeat 首次使用 Filebeat 请参阅入门指南 复制代码片段 curl L O https artifacts elastic co downloads beats filebeat filebeat 7 2 0
  • Windows驱动开发(一)第一个驱动程序

    首先我们需要了解 在操作系统中 是分两种权限的 一种是内核态 我们也称为0环 一种是用户态 称之为3环 而在我们的电脑中 驱动程序是运行在内核态的 这意味着和操作系统内核是在同一权限的 而普通的应用程序的权限是最低的 高权限谁不想拥有呢 因
  • 图解五种磁盘调度算法, FCFS, SSTF, SCAN, C-SCAN, LOOK

    一 FCFS 调度 先来先服务 磁盘调度的最简单形式当然是先来先服务 FCFS 算法 虽然这种算法比较公平 但是它通常并不提供最快的服务 例如 考虑一个磁盘队列 其 I O 请求块的柱面的顺序如下 98 183 37 122 14 124
  • linux 使用systemctl 启动服务报错: Error: No space left on device

    By default Linux only allocates 8192 watches for inotify which is ridiculously low And when it runs out the error is als
  • 操作系统常见面试题

    1 什么是进程 Process 和线程 Thread 有何区别 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动 进程是系统进行资源分配和调度的一个独立单位 线程是进程的一个实体 是CPU调度和分派的基本单位 它是比进程更小的能
  • 【操作系统】王道考研 p42 段页式管理方式

    段页式管理方式 知识总览 分段 分页管理方式中最大的优缺点 关于段式管理会产生外部碎片 ps 分段管理中产生的外部碎片也可以用 紧凑 来解决 只是需要付出较大的时间代价 分段 分页 段页式管理 示意图 先分段 后分页 段页式管理的逻辑地址结
  • gdb attach 进程调试

    gdb调试正在运行的进程 GDB可以对正在执行的程序进行调度 它允许开发人员中断程序 并查看其状态 之后还能让这个程序正常地继续执行 gdb attach xxxxx xxxxx为利用ps命令获得的子进程process
  • 《OSPF和IS-IS详解》一1.7 独立且平等

    本节书摘来自异步社区 OSPF和IS IS详解 一书中的第1章 第1 7节 作者 美 Jeff Doyle 更多章节内容可以访问云栖社区 异步社区 公众号查看 1 7 独立且平等 OSPF和IS IS详解与TCP IP相比 OSI协议对各国
  • I/O设备模型

    I O设备模型 绝大部分的嵌入式系统都包括一些I O Input Outut 输入 输出 设备 例如仪器上的数据显示屏 工业设备上的串口通信 数据采集设备上用于保存数据的Flash或SD卡 以及网络设备的以太网接口等 I O设备模型框架 R
  • 【操作系统xv6】学习记录4-一级页表与二级页表

    占位
  • 八股文打卡day20——操作系统(3)

    面试题 线程同步的方式有哪些 我的回答 多线程同时访问和修改某个数据的话 会造成数据的不一致和冲突问题 所以就需要线程同步 线程同步的方式有 1 互斥锁 互斥锁就是 当一个资源被访问和操作时 会对这个资源加锁 把这个资源锁定 其他线程不能对

随机推荐

  • 你知道项目的属性有哪些吗?

    项目的外资特征应该是其内在的属性 那么项目的属性都有哪些 项目的属性可以分为下面4各方面 项目有多目标属性 项目的目标又分为 成果性目标和约束性目标 成果性目标是一系列技术指标定义的 同时受到多种条件的约束 而约束性目标是多重的 所以项目有
  • 基于Java Socket通信实现聊天室功能

    目录 1 socket简介 2 架构图 3 服务器端详细过程 4 客户端详细过程 5 完整代码 1 socket简介 socket 翻译为 套接字 是计算机之间基于tcp协议的一种连接 两台存在socket连接的计算机可以发送 接收数据 在
  • Python与Stata在数据处理上的区别

    转自 微点阅读 https www weidianyuedu com 本节旨在演示如何在 pandas 中做各种类似Stata的操作 按照惯例 我们按如下方式导入 pandas 和 NumPy 计量经济学服务中心import pandas
  • 计算机中缺少vcruntime140d.dll (附下载链接,亲自试用可用)

    vcruntime140d dll下载地址 链接 https pan baidu com s 1bSigFLZHsjVbhdGs3zykGA 提取码 l0u2 win10系统 将dll复制到 C Windows SysWOW64 目录下 再
  • DBSCAN点云聚类

    1 DBSCAN算法原理 DBSCAN是一种基于密度的聚类方法 其将点分为核心点与非核心点 后续采用类似区域增长方式进行处理 下图为DBSCAN聚类结果 可见其可以对任意类别的数据进行聚类 无需定义类别数量 DBSCAN聚类说明 DBSCA
  • 网络-----浅析IP数据报格式及TCP/UDP报文段首部格式

    IP数据报的格式 先来上张图在解释 来看看每个字段的具体含义 只讨论IPV4的情况 1 版本 占4位 指IP协议的版本 通信双方使用IP协议的版本必须一致 例 使用IPV4即填4 2 首部长度 占4位 顾名思义 这个字段就是标识了IP数据报
  • nginx 部署多个vue项目 多文件方式 conf.d/*.conf

    在nginx conf目录下新建conf d文件夹 nginx conf ngxin conf worker processes 1 events worker connections 1024 http include mime type
  • vue学习笔记(超详细)

    文章目录 一 Vue基础 认识Vue js Vue安装方式 Vue的MVVM 二 Vue基础语法 生命周期 模板语法 创建Vue options可以放什么 语法 综合 v on v for遍历数组 v model表单绑定 v model结合
  • 使用iperf测试设备的网络吞吐量

    iperf简介 iperf是一个基于Client Server的网络性能测试工具 可以测试TCP UDP和SCTP带宽质量 能够提供网络吞吐量信息 以及震动 丢包率 最大段和最大传输单元通统计信息 帮助我们测试网络性能 定位网络瓶颈 ipe
  • Python入门之print()函数

    Python利用print 函数将结果输出到标准输出设备 即显示器 上 print 函数主要有以下几个参数 1 print objects objects 0个或多个输出对象 print 拥有0个参数 输出换行 print 函数拥有一个参数
  • SynchronizedMap

    Doug Lea的 util concurrent包除了包含许多其他有用的并发构造块之外 还包含了一些主要集合类型 List和 Map的高性能的 线程安全的实现 Brian Goetz向您展示了用 ConcurrentHashMap替换 H
  • 西瓜书第一章笔记

    本章从如何挑选西瓜的经验出发 介绍了本书所涉及基本术语和概念 数据集 样本 特征 属性 特征空间 属性空间 样本空间 输入空间 特征向量 维数 学习 训练 训练数据 训练样本 假设 预测 标记 样例 标记空间 输出空间 测试 测试样本 分类
  • PAT B1014

    include
  • arcgis创建公里格网并计算格网内点的平均值最后形成马赛克式栅格图

    生成公里格网 在搜索框搜索create fishnet 点击create fishnet output feature class 输出格网的位置和名字 template extent 公里格网的范围 和什么层相同 cell size wi
  • 电脑壁纸链接

    电脑壁纸链接 一 壁纸网站 1 彼岸图网 2 H128壁纸 3 Wallhaven 4 Wallhere 二 游戏壁纸 英雄联盟 神泣 鬼泣 女神联盟2 崩坏3 三国杀 QQ飞车 QQ炫舞 阴阳师 幻塔 王者荣耀 逆战 上古王冠 永恒魔法
  • springboot jar 启动 指定端口和编码格式

    java Dfile encoding utf 8 jar xxxx jar server port 8715
  • linux网络服务[网络配置]——————配置网络IP临时[ifconfig、ip]、永久[nmtui、nmcli、网络链接配置文件]

    文章目录 1 临时设定 1 1 ifconfig命令 1 1 1 安装命令 1 1 2 查看网卡设备 1 1 3 设置IP 1 2 ip命令 1 2 1 安装命令 1 2 2 设定ip 2 永久设置ip的方法 2 1 nmtui 2 2 n
  • OSPF路由汇总和外部路由汇总

    OSPF路由汇总和外部路由汇总 AR1 ospf 1 router id 11 11 11 11 area 0 0 0 1 network 1 1 1 1 0 0 0 0 network 172 16 0 0 0 0 255 255 net
  • 可变参数函数

    c c 支持可变参数的函数 即函数的参数是不确定的 一 为什么要使用可变参数的函数 一般我们编程的时候 函数中形式参数的数目通常是确定的 在调用时要依次给出与形式参数对应的所有实际参数 但在某些情况下希望函数的参数个数可以根据需要确定 因此
  • 常见锁相关

    Linux 锁 futex 所有的futex同步操作都应该从用户空间开始 首先创建一个futex同步变量 也就是位于共享内存的一个整型计数器 当进程尝试持有锁或者要进入互斥区的时候 对futex执行 down 操作 即原子性的给futex同