论文-分布式-并发控制-Lamport逻辑时钟

目录

前言

逻辑时钟讲解

算法类比为面包店内取号

Lamport算法的时间戳原理

Lamport算法的5个原则

举例说明

算法实现

参考文献


  • 前言

  • 在并发系统中,同步与互斥是实现资源共享的关键
  • Lamport面包店算法作为一种经典的解决并发问题的算法,它的实现原理和应用是每个探索并发控制的人必须要了解的知识点
  • Dijkstra于1965年提出的基于共享存储的临界区互斥访问问题
  • Dijkstra提出了基于对内存单元的原子性读写实现的方案
  • 然而,Lamport指出Dijkstra的方案会因为节点在临界区内失效而导致系统死锁
  • 在其于1974年发表的文章A New Solution of Dijkstra’s Concurrent Programming Problem中,Lamport提出了完全基于软件实现的解决方案,被称为“面包店算法”
  • Lamport面包店算法是一种经典的分布式系统中互斥访问共享资源的算法,用来解决多个线程并发访问一个共享的单用户资源的互斥问题,因其设计思想类似于面包店中取号排队的方式,因此被称为面包店算法
  • "面包店算法"模拟面包店内取号服务的模式,实现了先来先服务的的互斥访问
  • 这个算法也可以称为时间戳策略,或者叫做Lamport逻辑时钟
  • 逻辑时钟讲解

  • 这里先陈述一下这个逻辑时钟的内容:
  • 是一种在分布式系统中对事件进行时间戳排序的方法,在其中定义了因果关系,称为before
  • 例如,before在航班满员,航班可预订
  • 这里“事件预订”before“航班满员”,预订和满员就形成了因果关系
  • 现实世界中,确定事件预订发生在事件满员之前,需要预订发生在比满员更早的时间
  • 因果关系是一个事件(因)和第二个事件(果)之间的作用关系,其中后一个事件被认为是前一个事件的结果
  • 一般来说,一个事件是很多原因综合产生的结果,而且原因都发生在较早的时间点
  • 而在分布式系统中,有时不可能说两个事件中的一个首先发生;关系“happened before”只是系统中事件的部分排序
  • 我们用分布式系统中的事件的先后关系,用“->”符号来表示,例如:若事件a发生在事件b之前,那么a->b
  • 该关系需要满足下列三个条件:
    • 1-如果a和b是同一进程中的事件,a在b之前发生,则a->b
    • 2-如果事件a是消息发送方,b是接收方,则a->b
    • 3-对于事件a、b、c,如果有a->b,b->c,则有a->c
  • 注意,对于任何一个事件a,a->a都是不成立的,也就是说,关系->是反自反的
  • 有了上面的定义,我们也可以定义出“并发”(concurrent)的概念了:
    • 对于事件a、b,如果a->b,b->a两个都不成立,那么a和b就是并发的
  • 直观上,上面的->关系非常好理解,即“xxx在xxx之前发生”
  • 也就是说,一个系统在输入I1下,如果有a->b,那么对于这个系统的同一个输入I1,无论重复运行多少次,a也始终发生在b之前;
  • 如果在输入I1下a和b是并发的,则表示在同一个输入I1下的不同运行中,a可能在b之前,也可能在b之后,也可能恰好同时发生
  • 也就是说,并发并不是指一定同时发生,而是表示一种不确定性
  • ->和并发的概念,就是我们理解一个系统时最基础的概念之一了
  • 有了上面的概念,我们可以给系统引入时钟了
  • 这里的时钟就是lamport逻辑时钟
  • 一个时钟,本质上是一个事件到实数(假设时间是连续的)的函数
  • 这个函数将每个事件映射到一个数字,代表这个事件发生的时间
  • 形式一点来说,对于每个进程Pi,都有一个时钟Ci,这个时钟将该进程中的事件a映射到Ci(a)
  • 对于一个事件b,假设b属于进程Pj,那么C(b)=Cj(b)
  • 这里插一句,从这个定义也可以看到大师对分布式系统的理解
  • 分布式系统中不存在一个“全局”的实体
  • 在该系统中,每个进程都是一个相对独立的实体,它们有自己的本地信息(本地Knowledge)
  • 而整个系统的信息则是各个进程的信息的一个聚合
  • 有了时钟的一个“本质定义”还不够,我们需要考虑,什么样的时钟是一个有意义的,或者说正确的时钟
  • 其实,有了前文的->关系的定义,正确的时钟应满足的条件已经十分明显了:
  • 时钟条件:对于任意两个事件a,b,如果a->b,那么C(a)<C(b)
  • 注意,反过来讲这个条件可不成立
  • 如果我们要求反过来也成立,即“如果a->b为假,那么C(a)<C(b)也为假”,那就等于要求并发事件必须同时发生,这显然是不合理的
  • 结合前文->关系的定义,我们可以把上面的条件细化成如下两条:
    • 1-如果a和b是进程Pi中的两个事件,并且在Pi中,a在b之前发生,那么Ci(a)<Ci(b)
    • 2-如果a是Pi发送消息m,b是Pj接收消息m,那么Ci(a)<Cj(b)
  • 上面就定义了合理的逻辑时钟
  • 显然,一个系统可以有无数个合理的逻辑时钟
  • 实现逻辑时钟也相对简单,只要遵守两条实现规则就可以了:
    • 1-每个进程Pi在自己的任何两个连续的事件之间增加Ci值
    • 2-如果事件a是Pi发送消息m,那么在m中应该带上时间戳Tm=Ci(a);如果b是进程Pj接收到消息m,那么,进程Pj应该设置Cj为大于max(Tm,Cj(b))
  • 有了上面逻辑时钟的定义,我们现在可以为一个系统中所有的事件排一个全序,就是使用事件发生时的逻辑时钟读数进行排序,读数小的在先
  • 当然,此时可能会存在两个事件同时发生的情况
  • 如果要去除这种情况,方法也非常简单:如果a在进程Pi中,b在进程Pj中,Ci(a)=Cj(b)且i < j,那么a在b之前
  • 形式化一点,我们可以把系统事件E上的全序关系“=>”定义为:
  • 假设a是Pi中的事件,b是Pj中的事件,那么:a=>b当且仅当以下两个条件之一成立:
    • 1-Ci(a)<Cj(b)
    • 2-Ci(a)=Cj(b) 且 i < j
  • 算法类比为面包店内取号

  • Lamport把上面这些数理逻辑时钟的概念以非常直观地类比为顾客去面包店采购
  • 面包店只能接待一位顾客的采购
  • step1:已知有n位顾客要进入面包店采购,安排他们按照次序在前台登记一个签到号码;该签到号码逐次加1
  • step2:根据签到号码的由小到大的顺序依次入店购货
  • step3:完成购买的顾客在前台把其签到号码归0;如果完成购买的顾客要再次进店购买,就必须重新排队
  • 这个类比中的顾客就相当于线程,而入店购货就是进入临界区独占访问该共享资源
  • 由于计算机实现的特点,存在两个线程获得相同的签到号码的情况,这是因为两个线程几乎同时申请排队的签到号码,读取已经发出去的签到号码情况,这两个线程读到的数据是完全一样的,然后各自在读到的数据上找到最大值,再加1作为自己的排队签到号码
  • 为此,该算法规定如果两个线程的排队签到号码相等,则线程id号较小的具有优先权
  • 进入临界区
    • 已经拿到排队签到号码的线程,要轮询检查自己是否可以进入临界区
    • 即检查n个线程中,自己是否具有最小的非0排队签到号码;或者自己是具有最小的非0排队签到号码的线程中,id号最小的
    • 可以用伪代码表示上述检查:

  • 非临界区
    • 一旦线程在临界区执行完毕,需要把自己的排队签到号码置为0,表示处于非临界区
  • 把该算法原理与分布式系统相结合,即可实现分布式锁
  • 注意这个系统中需要引入时钟同步,博主的意见是可以采用SNTP实现时钟同步(非权威,仅供参考)
  • Lamport算法的时间戳原理

  • 由部分排序可知,问题的关键点在于节点间的交互要在事件发生顺序上达成一致,而不是对于时间达成一致
  • 所以,逻辑时钟指的是分布式系统中用于区分时间发生顺序的机制
  • 从某种意义上来讲,现实世界的物理时间其实是逻辑时钟的特例
  • 分布式系统中,按是否存在节点交互可分为三类事件,节点内部,发送事件,接收事件
  • 每个事件对应一个Lamport时间戳,初始值为0
  • 如果事件在节点内发生,时间戳+1
  • 如果事件属于发送事件,时间戳+1并在消息中带上该时间戳
  • 如果事件属于接收事件,时间戳=Max(本地时间戳,消息中的时间戳)+1
  • Lamport算法的5个原则

  • 通过五条规则定义算法,为了方便起见,假设每个规则定义的操作形成单个事件:
    • 为了请求资源,进程A发送消息(Tm:A)给所有的其他进程,并且把这个消息放到进程队列中,Tm是消息的时间戳
    • 当进程B接收到了进程A的(Tm:A)请求后,会把它放到自己的请求队列,然后发送一个带有时间戳的确认消息给A
    • 为了释放资源,进程A移除所有(Tm:A)的请求消息,然后发送带时间戳的A释放资源请求消息给其他所有的进程
    • 当进程B接收到进程A释放资源的请求,它会移除队列中任意的(Tm:A)的请求资源
    • 当满足以下两个条件时,进程A会被赋予资源:
      • 1-有一个(Tm:A)的请求,按照=>关系排在队列第一位(它在队列中=>其他请求(为了定义=>,我们定义一个消息,使用发送消息的事件来识别))
      • 2-A接收到了一个时间戳大于Tm的来自所有其他进程的消息
  • 举例说明

  • 在下面这幅图中,我们可以看到现在有三个进程请求临界资源,分别是P1,P2,P3
  • 在P2时间戳=33时,时间戳+1,P2将34写入自己的队列,P2发送request信号分别给三个进程

  • 在P3时间戳=38时,P3收到P2的request信号,将34写入自己的队列,P3时间戳+1,向P2发送时间戳为39的reply信号

  • 在P1时间戳=40时,P1时间戳+1,P1将41写入自己的队列,P1发送request信号分别给三个进程;此时P1还没有收到P2的请求信号

  • 在P1时间戳=42时,P1收到P2的request信号,将34写入自己的队列,P1时间戳+1,向P2发送时间戳为43的reply信号

  • 在P2收到其中一个进程的reply信号后,因为队头是自己的时间戳,所以P2进入临界区开始使用资源

  • 在P3时间戳=42时,P3收到P1的request信号,将41写入自己的队列,P3时间戳+1,向P1发送时间戳为43的reply信号

  • 在P2时间戳=42时,P2收到P1的request信号,将41写入自己的队列,P2时间戳+1,向P1发送时间戳为43的reply信号

  • 在P2时间戳=48时,向其他两个进程发送release信号,并将其在本地队列中释放,也在其他队列中释放

  • 现在我们可以通过这个时空图回顾一下上述过程

  • 注意到在本地时间44,P2或许开始使用资源,因为它已经收到来自P1值为41的时间戳的消息,比P2值为34的时间戳的需求消息更大
  • 此算法按照“发生在先”关系的顺序授予资源(无优先级倒置)
  • 算法实现

  • 定义
    • 数组Choosing[i]为真,表示进程i正在获取它的排队登记号
    • 数组Number[i]的值,是进程i的当前排队登记号;如果值为0,表示进程i未参加排队,不想获得该资源;规定这个数组元素的取值没有上界
    • 正在访问临界区的进程如果失败,规定它进入非临界区,Number[i]的值置0,即不影响其它进程访问这个互斥资源
  • 代码

  • 细节讨论
    • 每个线程只写它自己的Choosing[i]、Number[i],只读取其它线程的这两个数据项
    • 这个算法不需要基于硬件的原子(atomic)操作实现,即它可以纯软件实现
    • 使用Choosing数组是必须的
    • 假设不使用Choosing数组,那么就可能会出现这种情况:
      • 设进程i的优先级高于进程j(即i<j),两个进程获得了相同的排队登记号(Number数组的元素值相等)
      • 进程i在写Number[i]之前,被优先级低的进程j抢先获得了CPU时间片,这时进程j读取到的Number[i]为0,因此进程j进入了临界区
      • 随后进程i又获得CPU时间片,它读取到的Number[i]与Number[j]相等,且i<j,因此进程i也进入了临界区
      • 这样,两个进程同时在临界区内访问,可能会导致数据腐烂(data corruption)
      • 算法使用了Choosing数组变量,使得修改Number数组的元素值变得“原子化”,解决了上述问题
    • 具体实现时,可以把上述伪代码中的忙等待(busy wait),换成交出线程的执行权,例如yield操作
  • 参考文献

  • Original Paper
  • On his publications page,Lamport has added some remarks regarding the algorithm

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/170556.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

opencalib中lidar2camera安装记录

目录 一、opencalib安装 二、lidar2camera的安装 三、测试运行 四、出现过的问题 一、opencalib安装 代码地址&#xff1a;https://github.com/PJLab-ADG/SensorsCalibration/blob/master/README.md # pull docker image sudo docker pull scllovewkf/opencalib:v1 # Aft…

出海路上离不开的Email营销,教你这样来优化!

随着互联网的不断发展&#xff0c;Email已经成为人们工作和生活中不可或缺的一部分。尤其是对于我们这些跨境企业而言&#xff0c;发送Email是一个促进销售和维护客户关系的良好渠道。而且邮件的价格也是比较低廉的&#xff0c;很适合用于日常推广营销&#xff0c;所以人手几个…

【Linux】nginx基础篇 -- 介绍及yum安装nginx

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

光影之梦2:动画渲染前后对比,揭示视觉艺术的惊人转变!

动画渲染是影视艺术中不可或缺的一环&#xff0c;它赋予了角色和场景鲜活的生命。渲染过程中的光影、色彩、材质等元素&#xff0c;像是画家的调色板&#xff0c;将平淡无奇的线条和形状转化为充满韵味与情感的画面。动画角色仿佛拥有了自己的灵魂&#xff0c;无论是一颦一笑&a…

Unity Inspector编辑器扩展,枚举显示中文,枚举值自定义显示内容

记录&#xff01;Unity Inspector面板编辑器扩展&#xff0c;枚举显示中文&#xff0c;枚举值自定义显示内容&#xff0c;显示部分选项。效果如下&#xff1a; 枚举类代码&#xff1a; using System.Collections; using System.Collections.Generic; using UnityEngine;public…

9 线程池

目录 1 线程池各参数 1.1 corePoolSize 1.2 maximunPoolSize 1.3 keepAliveTime 1.4 workQueue 1.5 RejectedExecutionHandler 2 线程池工作机制 2.1 流程 2.2 提交任务 3 相关问题 3.1 线程池核心线程数、最大线程数设置 3.2 ApiPost压测 3.3 为什么要用阻塞队列…

初识Java篇

1.介绍Java语言 1.1Java是什么 Java是一种优秀的程序设计语言&#xff0c;它具有令人赏心悦目的语法和易于理解的语义。 不仅如此&#xff0c;Java还是一个有一系列计算机软件和规范形成的技术体系&#xff0c;这个技术体系提供了完整的用于软件开发和跨平台部署的支持环境&am…

小知识(5) el-table行样式失效问题

一、实现效果 子级呈现不同颜色去区分 二、最初代码 tips: 我这里使用的vue3 elementplus <el-table :row-class-name"tableRowClassName" >... </el-table>function tableRowClassName({ row, rowIndex }) {if (row.children.length 0) {return …

基于ElasticSearch+Vue实现简易搜索

基于ElasticSearchVue实现简易搜索 一、模拟数据 产品名称描述价格库存数量品牌名称智能手表智能手表&#xff0c;具有健康跟踪和通知功能。199.991000TechWatch4K智能电视4K分辨率智能电视&#xff0c;提供出色的画质。699.99500VisionTech无线耳机降噪无线耳机&#xff0c;…

html iframe 框架有哪些优缺点?

目录 前言&#xff1a; 用法&#xff1a; 理解&#xff1a; 优点&#xff1a; 嵌套外部内容&#xff1a; 独立性&#xff1a; 分离安全性&#xff1a; 跨平台兼容性&#xff1a; 方便维护&#xff1a; 缺点&#xff1a; 性能开销&#xff1a; 用户体验问题&#xf…

【网安大模型专题10.19】※论文5:ChatGPT+漏洞定位+补丁生成+补丁验证+APR方法+ChatRepair+不同修复场景+修复效果(韦恩图展示)

Keep the Conversation Going: Fixing 162 out of 337 bugs for $0.42 each using ChatGPT 写在最前面背景介绍自动程序修复流程Process of APR (automated program repair)1、漏洞程序2、漏洞定位模块3、补丁生成4、补丁验证 &#xff08;可以学习的PPT设计&#xff09;经典的…

独家揭秘微信视频号下载提取器,使用方法!

1&#xff1a;微信视频号下载提取器&#xff0c;需要先确认自己手机电脑版本是否支持视频号的观看和浏览 2:需要下载视频号的作品发给视频下载小助手&#xff0c;聊天窗口 3&#xff1a;打开小助手解析视频号视频链接&#xff0c;保存到手机相册或者电脑上 注意视频号电脑版…

适用于 Linux 和 Unix 的特权访问管理

凭据、SSH 密钥、服务帐户、数字签名、文件系统等内容构成了Linux 环境的关键部分&#xff0c;虽然大多数PAM供应商为基于Windows的环境提供无缝的特权访问管理&#xff0c;但它们的通用性不足以为Linux&#xff0c;Unix和*nix环境扩展相同的功能和功能。 Linux 中的root权限是…

wf-docker集群搭建(未完结)

系列文章目录 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 系列文章目录前言一、redis集群二、mysql集群三、nacos集群1. 环境要求2. 拉取镜像2.1. 拉取镜像方式配置集群2.2. 自定义nacos镜像配置集群 3 自定义…

基于PHP的图像分享社交平台

有需要请加文章底部Q哦 可远程调试 基于PHP的图像分享社交平台 一 介绍 此图像分享社交平台基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。平台角色分为用户和管理员。用户可注册登录&#xff0c;发布图像&#xff0c;修改个人信息&#xff0c;评论图像…

分享一下门店服务预约系统怎么做

随着科技的不断发展&#xff0c;越来越多的企业开始注重提高服务质量和效率。其中&#xff0c;门店服务预约系统成为了许多企业的选择。本文将探讨门店服务预约系统的意义、设计思路、实现方法、系统测试以及拓展案例&#xff0c;并总结门店服务预约系统设计和实现的重要性。 一…

国腾GM8775C完全替代CS5518 MIPIDSI转2 PORT LVDS

集睿致远CS5518描述&#xff1a; CS5518是一款MIPI DSI输入、LVDS输出转换芯片。MIPI DSI 支持多达4个局域网&#xff0c;每条通道以最 大 1Gbps 的速度运行。LVDS支持18位或24位像素&#xff0c;25Mhz至154Mhz&#xff0c;采用VESA或JEIDA格 式。它只能使用单个1.8v电源&am…

更改idea的JDK版本

有时候我们需要更改 idea 的 JDK 版本&#xff0c;这里告诉大家更改的方法&#xff0c;非常简单快捷&#xff0c;而且也不需要去找 JDK 的资源 1.在 idea 的左上角找到 File 选择 Peoject Structure 2.在页面左上角找到 Project &#xff0c;点击 SDK 的框&#xff0c;选择 A…

RISC-V架构——中断委托和中断注入

1、中断委托 1.1、中断委托的作用 &#xff08;1&#xff09;默认情况下&#xff0c;所有的陷入&#xff08;中断和异常&#xff09;都是在M模式下处理&#xff0c;然后再返回到发生陷入前的模式&#xff1b; &#xff08;2&#xff09;所有陷入都在M模式处理会涉及到模式切换…

将自己本地项目上传到git,增加IDEA操作

文章目录 一、初始化git仓库二、gitee创建仓库三、输入自己仓库的地址四、在添加所修改的文件可能的错误 五、合并需上传文件六、上传参考文档 一、初始化git仓库 在自己的项目中&#xff0c;命令行中输入 git init二、gitee创建仓库 新建仓库 设置仓库参数&#xff0c;设置…