📜  兰波特的逻辑时钟

📅  最后修改于: 2021-10-23 07:30:24             🧑  作者: Mango

Lamport 的逻辑时钟是由 Leslie Lamport 创建的。它是确定事件发生顺序的过程。它为更高级的矢量时钟算法提供了基础。由于分布式操作系统中缺少全局时钟,因此需要 Lamport 逻辑时钟。

算法:

  • 发生在关系(->)之前: a -> b,意味着“a”发生在“b”之前。
  • 逻辑时钟:逻辑时钟的标准是:
    • [C1]: C i (a) < C i (b), [ C i -> 逻辑时钟,如果’a’发生在’b’之前,那么’a’的时间将小于’b’在特定情况下过程。 ]
    • [C2]:C i (a) < C j (b),[ C i (a) 的时钟值小于C j (b) ]

参考:

  • 工艺: P i
  • 事件: E ij ,其中 i 是进程编号, j:i进程中的第 j个事件。
  • t m消息 m 的向量时间跨度。
  • C i向量时钟与进程P 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 jT 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) < C(b) -> 为真。
  • 在 [IR2] 的情况下,如果 a -> b,则 C(a) < C(b) -> 可能为真,也可能不为真。

下面是实现 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;
}


C++
// C++ program to illustrate the Lamport's
// Logical Clock
 
#include 
using namespace std;
 
// 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;
 
    cout << "\nThe time stamps of "
         "events in P1:\n";
 
    for (i = 0; i < e1; i++) {
        cout << p1[i] << " ";
    }
 
    cout << "\nThe time stamps of "
         "events in P2:\n";
 
    // Print the array p2[]
    for (i = 0; i < e2; i++)
        cout << 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++)
        cout << "\te2" << i + 1;
 
    for (i = 0; i < e1; i++) {
 
        cout << "\n e1\t" << i + 1;
 
        for (j = 0; j < e2; j++)
            cout << m[i][j] << "\t";
    }
 
    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

时间复杂度: O(e1 * e2 * (e1 + e2))
辅助空间: O(e1 + e2)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。