Lamport的逻辑时钟由Leslie Lamport创建。这是确定事件发生顺序的过程。它为更高级的矢量时钟算法提供了基础。由于分布式操作系统中没有全局时钟,因此需要Lamport逻辑时钟。
算法:
- 发生在关联(->):a- > b之前,表示“ a”发生在“ b”之前。
- 逻辑时钟:逻辑时钟的标准是:
- [C1]:C i (a)
i (b),[C i- >逻辑时钟,如果“ a”发生在“ b”之前,则特定时间中“ a”的时间将小于“ b”过程。 ] - [C2]:C i (a)
j (b),[C i (a)的时钟值小于C j (b)]
- [C1]:C i (a)
参考:
- 工艺: P i
- 事件: E ij ,其中i是数字中的过程, j是第i个过程中的第j个事件。
- t m :消息m的向量时间跨度。
- 与进程P i相关联的C i矢量时钟,第j个元素是Ci [j] ,其中包含进程P j中当前时间的P i最新值。
- d:漂移时间,通常d为1。
实施规则[IR]:
- [IR1]:如果a-> b [[a]在同一过程中发生在’b’之前],则C i (b)= C i (a)+ d
- [IR2]: C j = max(C j ,t m + d)[如果进程数量更多,则t m = C i (a)的值,C j = C j与t m + d之间的最大值]
例如:
- 取起始值为1,因为它是第1个事件并且存在在起始点没有传入的值:
- e11 = 1
- e21 = 1
- 如果没有输入值,即跟随[IR1],则下一点的值将继续增加d(d = 1)。
- e12 = e11 + d = 1 +1 = 2
- e13 = e12 + d = 2 +1 = 3
- e14 = e13 + d = 3 +1 = 4
- e15 = e14 + d = 4 +1 = 5
- e16 = e15 + d = 5 +1 = 6
- e22 = e21 + d = 1 + 1 = 2
- e24 = e23 + d = 3 +1 = 4
- e26 = e25 + d = 6 +1 = 7
- 当会有输入值时,请遵循[IR2],即取C j与T m + d之间的最大值。
- e17 = max(7,5)= 7,[e16 + d = 6 +1 = 7,e24 + d = 4 +1 = 5,7和5中的最大值是7]
- e23 = max(3,3)= 3,[e22 + d = 2 +1 = 3,e12 + d = 2 +1 = 3,3和3之间的最大值是3]
- e25 = max(5,6)= 6,[e24 +1 = 4 +1 = 5,e15 + d = 5 +1 = 6,5和6中的最大值为6]
局限性:
- 在[IR1]的情况下,如果a-> b,则C(a)
true。 - 在[IR2]的情况下,如果a-> b,则C(a)
可以为真,也可以不为真。
以下是实现Lamport逻辑时钟的C程序:
C
// C program to illustrate the Lamport's
// Logical Clock
#include
// Function to find the maximum timestamp
// between 2 events
int max1(int a, int b)
{
// Return the greatest of th two
if (a > b)
return a;
else
return b;
}
// Function to display the logical timestamp
void display(int e1, int e2,
int p1[5], int p2[3])
{
int i;
printf("\nThe time stamps of "
"events in P1:\n");
for (i = 0; i < e1; i++) {
printf("%d ", p1[i]);
}
printf("\nThe time stamps of "
"events in P2:\n");
// Print the array p2[]
for (i = 0; i < e2; i++)
printf("%d ", p2[i]);
}
// Function to find the timestamp of events
void lamportLogicalClock(int e1, int e2,
int m[5][3])
{
int i, j, k, p1[e1], p2[e2];
// Initialize p1[] and p2[]
for (i = 0; i < e1; i++)
p1[i] = i + 1;
for (i = 0; i < e2; i++)
p2[i] = i + 1;
for (i = 0; i < e2; i++)
printf("\te2%d", i + 1);
for (i = 0; i < e1; i++) {
printf("\n e1%d \t", i + 1);
for (j = 0; j < e2; j++)
printf("%d\t", m[i][j]);
}
for (i = 0; i < e1; i++) {
for (j = 0; j < e2; j++) {
// Change the timestamp if the
// message is sent
if (m[i][j] == 1) {
p2[j] = max1(p2[j], p1[i] + 1);
for (k = j + 1; k < e2; k++)
p2[k] = p2[k - 1] + 1;
}
// Change the timestamp if the
// message is reeived
if (m[i][j] == -1) {
p1[i] = max1(p1[i], p2[j] + 1);
for (k = i + 1; k < e1; k++)
p1[k] = p1[k - 1] + 1;
}
}
}
// Function Call
display(e1, e2, p1, p2);
}
// Driver Code
int main()
{
int e1 = 5, e2 = 3, m[5][3];
// message is sent and received
// between two process
/*dep[i][j] = 1, if message is sent
from ei to ej
dep[i][j] = -1, if message is received
by ei from ej
dep[i][j] = 0, otherwise*/
m[0][0] = 0;
m[0][1] = 0;
m[0][2] = 0;
m[1][0] = 0;
m[1][1] = 0;
m[1][2] = 1;
m[2][0] = 0;
m[2][1] = 0;
m[2][2] = 0;
m[3][0] = 0;
m[3][1] = 0;
m[3][2] = 0;
m[4][0] = 0;
m[4][1] = -1;
m[4][2] = 0;
// Function Call
lamportLogicalClock(e1, e2, m);
return 0;
}
输出:
e21 e22 e23
e11 0 0 0
e12 0 0 1
e13 0 0 0
e14 0 0 0
e15 0 -1 0
The time stamps of events in P1:
1 2 3 4 5
The time stamps of events in P2:
1 2 3