常见锁相关

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(使用前将#替换为@)

常见锁相关 的相关文章

  • window系统消失的c盘,实际占用与显示占用相差好多G

    问题 C盘一直显示的红色提醒 我c盘实际占用的空间只有33 1GB 而我的c盘总共大小是59 9GB 显示的剩余大小是1 35GB 也就是说我占用了58 11 和c盘的总文件大小相差了25GB 那么消失的25GB去了哪里 我百度过这个问题
  • fork之后子进程到底复制了父进程什么

    fork之后子进程到底复制了父进程什么 发表于2015 4 3 9 54 08 2161人阅读 分类 操作系统 include
  • texlive支持中文的简单方法

    1 确保tex文件的编码方式是UTF 8 2 在文档开始处添加一行命令即可 即 usepackage UTF8 ctex 如下所示 documentclass article usepackage UTF8 ctex begin artic
  • Win11微软账号登录不上?Win11登录Microsoft账户出错的解决方法

    Win11微软账号登录不上 近期有部分Win11用户反映在登录微软账号会出现一直转圈 无法登录的情况 这样导致部分功能都不能正常使用了 为此十分令人头疼 那么对于这一情况 有没有什么方法可以有效的解决呢 下面小编教给大家操作方法 大家可以去
  • windows下命令行修改系统时间;修改系统时间的软件

    找了很久 都没有找到 还找了关键词 dos下修改系统时间 因为看到linux下修改系统时间是用hwclock 命令写入主板芯片 而我由于某些原因想自动化修改系统时间 所以找windows下修改系统时间的软件 没有找到 有一个 意天禁止修改系
  • 计算机领域中随处可见的抽象

    想要管理多种具体的东西 那么需要遵守每种东西的规范 如果想要提供一种通用模式来对这些具体的东西统一管理 需要使用一种古老的技术 抽象 抽象是将多种具体的东西 管理时需要遵守的规范 的共同点抽取出来 放入到更高一层的抽象层 在抽象层不定义或少
  • 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 进程 线
  • JSON.stringify()

    JSON stringify 将一个JavaScript值 对象或者数组 转换为一个 JSON字符串 如果指定了replacer是一个函数 则可以选择性的替换值 或者如果指定了replacer是一个数组 可选择性的仅包含数组指定的属性 语法
  • win10 Enable developer Mode

    经过漫长的安装过程 win10终于装上了vs2015 rc 写个小程序试试 结果提示 根据提示打开 设置 更新 for developer 据说应该有这么个界面 但是这个界面根本出不来 直接闪退的说 翻 MSDN 终于翻出了解决方法 htt
  • 安装黑苹果双系统专辑贴(持续更新...)

    最近终于开始研究黑苹果 然后浏览了几篇文章贴收集一下 以便需要时随时阅览 和同学们互相学习 零基础篇 1 https blog csdn net a792396951 article details 80230946 2 https zhu
  • 03LinuxC线程学习之线程共享和非共享

    1 线程共享和非共享 1 1 线程共享资源 1 文件描述符表 由于线程间共享进程间的内容 而文件描述符表在主线程的PCB当中 各个线程可以直接去请求访问 所以线程间通信就不需要像进程那样通过管道这些方式通信 2 每种信号的处理方式 即当某个
  • Visual studio 2005 hangs on startup AppHangXProcB1 svchost devenv.exe svchost.exe:{2a811bb2-303b-48b...

    This problem has been torturing me for the whole afternoon and after searching on the web for a long time I finally get
  • [架构之路-185]-《软考-系统分析师》-3-操作系统基本原理 - 文件索引表

    目录 一 文件的索引块 二 索引分配表 三 索引表的链接方案 四 多层索引 五 混合索引分配 一 文件的索引块 存放在目录中的文件 并非是文件的真实内容 目录中记录了文件的索引块是几号磁盘块 文件对应的索引表是存放在指定的磁盘块中的 二 索
  • 内存管理——分页分段

    一 分页存储管理 1 页面与页框 1 页面 将一个进程的逻辑地址空间分成若干个大小相等的片 称为页面或页 并为各页加以编号 2 页框 相应于页面 把内存空间分成和页面相同大小的若干个存储块 称为 物理 块或页框 frame 3 页内碎片 在
  • 图解五种磁盘调度算法, FCFS, SSTF, SCAN, C-SCAN, LOOK

    一 FCFS 调度 先来先服务 磁盘调度的最简单形式当然是先来先服务 FCFS 算法 虽然这种算法比较公平 但是它通常并不提供最快的服务 例如 考虑一个磁盘队列 其 I O 请求块的柱面的顺序如下 98 183 37 122 14 124
  • C#实现FTP文件夹下载功能【转载】

    网上有很多FTP单个文件下载的方法 前段时间需要用到一个FTP文件夹下载的功能 于是找了下网上的相关资料结合MSDN实现了一段FTP文件夹下载的代码 实现的思路主要是通过遍历获得文件夹下的所有文件 当然 文件夹下可能仍然存在文件夹 这样就需
  • Linux(13):例行性工作排程

    例行性工程 听谓的排程是将工作安排执行的流程之意 Linux 排程就是透过 crontab 与 at 这两个东西 两种工作排程的方式 一种是例行性的 就是每隔一定的周期要来办的事项 一种是突发性的 就是这次做完以后就没有的那一种 at at
  • 【操作系统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同