lamport面包店算法详细讲解及代码实现
lamport面包店算法详细讲解及代码实现
- 1 算法详解
- 1.1 一个较为直观的解释
- 1.2 Lamport算法的时间戳原理
- 1.3 Lamport算法的5个原则
- 1.4 一个小栗子
- 2 算法实现
- 3 适用领域
1 算法详解
1978年Lamport发表的文章《Time, Clocks, and the Ordering of Events in a Distributed System》
算法检查了分布式系统中一个事件先于另一个时间发生的概念,并且定义了时间的偏序,给出了一种用于同步逻辑时钟系统的分布式算法。该系统可用于对事件进行完全排序。使用解决同步问题的方法说明了总排序的使用。该算法专门用于同步物理时钟,并推导出时钟可能不同步的程度。
有兴趣的读者可以深入阅读这篇论文!
链接:https://dl.acm.org/doi/pdf/10.1145/359545.359563
1.1 一个较为直观的解释
lamport算法又称为面包店算法,它解决了多个线程并发访问一个共享的单用户资源的互斥问题的算法。
Lamport把这个并发控制算法直观的类比为顾客去面包店采购。这个步骤如下所示:
step1: 有n个顾客进入面包房买巧克力面条蒸蛋糕,安排他们按照次序在前台登记签到的号码。该签到号码依次加1.
step2: 根据签到号码的由小到大的顺序依次进店买好吃的蛋糕。
step3: 完成购物的顾客在前台把自己的签到号码归0。如果完成购买的顾客要再次进店需要重新排队。
特别说明: 同时进入面包店采购的两个或两个以上的顾客有可能得到相同的号码,多个顾客如果拿到相同的号码,则规定按照顾客名字的字典顺序进行排序。
抽象对应:
顾客--------------------->进程
入店购货--------------->进入临界区独占访问共享资源
相同号码---------------->由于计算机实现的特点,存在两个线程获得相同的签到号码的情况,这是因为两个线程几乎同时申请排队的签到号码,两个线程读到的号码是完全一样的,所以,在该算法中规定如果两个线程的排队签到号码相等,则线程id号较小的具有优先权。
1.2 Lamport算法的时间戳原理
- 每个事件对应一个Lamport时间戳,初始值为0;
- 如果事件在节点内发生,时间戳+1;
- 如果事件属于发送事件,时间戳+1并在消息中带上该时间戳;
- 如果事件属于接收事件,时间戳=Max(本地时间戳,消息中的时间戳)+1。
1.3 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的来自所有其他进程的消息。
1.4 一个小栗子
在上面这幅图中,我们可以看到现在有三个进程请求临界资源,分别是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信号。
在P1时间戳=48时,像其他两个进程发送release信号,并将其在本地队列中释放,也在其他队列中释放。
现在我们可以通过这个时空图回顾一下上述过程。
注意到在本地时间44, P2 或许开始使用资源,因为它已经收到来自P1值为41的时间戳的消息,比P2值为34的时间戳的需求消息更大.
此算法按照“发生在先”关系的顺序授予资源(无优先级倒置).
2 算法实现
废话不多说,我直接就上代码了!
#define true 1
#define false 0
#define process_num 4//线程数目
int choosing[process_num]={false};
int number[process_num]={0};//排队签到号码//找出最大的号码
int find_max(void)
{int max=0;for(int i=0;i<process_num;++i){if(number[i]>max)max=number[i];}return max;
}void enter_lock(int thread_id)
{choosing[thread_id]=true;number[thread_id]=find_max()+1;//选号码choosing[thread_id]=false;for(int i=0;i<process_num;++i){while(choosing[i]);//等待其他线程选号码while((number[i] != 0)&&( (number[i] < number[thread_id]) || ((number[i] == number[thread_id]) && (i < thread_id)) ));//阻塞,等待调度}
}//释放号码
void exit_lock(int thread_id)
{number[thread_id]=0;//释放号码
}
3 适用领域
1.适合节点数目少且变动不频繁的系统,且由于每个程序均需通信交互,因此适合 P2P 结构的系统。
2.Hadoop 是我们非常熟悉的分布式系统,其中的分布式文件系统 HDFS 的文件修改就是一个典型的应用分布式算法的场景。
以上就是本人对于lamport算法的相关理解,如果有什么疏漏之处还请大家批评指正!
lamport面包店算法详细讲解及代码实现相关推荐
- 模拟退火算法详细讲解(含实例python代码)
模拟退火算法详细讲解(含实例python代码) (一)模拟退火算法简介 (二)模拟退火算法原理 (三)退火过程中参数控制 (四)算法步骤 (五)实例分析 最近老师要求做模拟退火算法实验,看了很多博客之 ...
- 【OS系列-2】- 进程详细讲解(代码示例)
进程 进程详细讲解(代码示例) 进程 示例代码 创建进程的具体过程? 执行 fork()的时候系统做了什么? 进程间通信 管道 消息队列 共享内存 信号量 套接字 进程间同步 信号量 文件锁 无锁 C ...
- Adaboost算法详细讲解
转自线上数据建模 Adaboost算法详细讲解 Adaboost(Adaptive Boosting): Adaboost是Boosting模型,和bagging模型(随机森林)不同的是:Adaboo ...
- dijkstra标号法表格_Dijkstra算法详细讲解
最短路径之 Dijkstra 算法详细讲解 1 最短路径算法 在日常生活中,我们如果需要常常往返 A 地区和 B 地区之间,我们最希望 知道的可能是从 A 地区到 B 地区间的众多路径中,那一条路径的 ...
- 深度学习:NiN(Network In Network)详细讲解与代码实现
深度学习:NiN(Network In Network)详细讲解与代码实现 网络核心思想 1*1卷积 NiN块的作用 全局池化(Global Average Pooling) 基于NiN的服装分类(P ...
- Java对象,Map,List,Set数组等相互转换大全(详细讲解,附代码,讲解案例)
Java对象,Map,List,Set数组等相互转换大全(详细讲解,附代码,讲解案例) Java对象 转 JSON字符串 JAVA对象转MAP Map转java对象 List转map List和Map ...
- C语言老鼠走迷宫(单路径)算法详细讲解
最近在学习C语言的一些经典算法,其中遇到了一点困难,导致卡进度了.琢磨了很久,在绘制流程图时,突然灵感大开理解了,老鼠走迷宫算法的奇妙.所以写了这个,一来是方便以后右和我类似的同学自学时,遇到这个问题 ...
- Dijkstra算法 详细讲解
Dijkstra算法 详细解释 Dijkstra算法适用于边权值为正的情况,如果边权值为负数就才用另一种最短路算法Bellman-Ford算法. 该算法是指从单个源点到各个结点的最短路,该算法适用于有 ...
- 排序算法详细讲解(超酷)
目录 前言 一.插入类排序 1.直接插入排序 2.折半插入排序 3.希尔排序 二.交换类排序 1.冒泡排序(相邻比序法) 2.快速排序 三.选择类排序 1.简单选择排序 2.树形选择排序 3.堆排序 ...
最新文章
- 双链表偶数节点求和java_java--删除链表偶数节点
- C#_数据库基本交互
- Linux之telnet命令使用详解—网络故障定位(四)
- BeanUtils.copyProperties VS PropertyUtils.copyProperties
- LeetCode 46. 全排列(回溯)
- JavaScript var语句简析
- linux下免密认证登录失败原因总结
- Max(TM)仓库管理系统v2.0.5.1网络版
- 1156 Sexy Primes – PAT甲级真题
- 关于下载Keil5无法打开keil4文件的问题解决方案
- Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
- 修复计算机命令行,命令提示符修复系统方法
- TransCenter: Transformers with Dense Queries for Multiple-Object Tracking
- 启发式算法,元启发式算法,超启发式算法
- chcp Command的妙用
- 利用机队数据训练的性能模型检测飞机异常
- css3炫彩边框渐变色动画js特效
- 学好AI和PS就能成为设计师?抱歉,你还缺个Adobe国际认证证书!
- Jenkins+jmeter+ant自动化设置jira面板统计图每日更新
- 用css实现三横的代码