📜  硬件同步算法:解锁和锁定,测试和设置,交换

📅  最后修改于: 2021-08-27 06:39:43             🧑  作者: Mango

当同时运行的两个进程共享相同的数据或相同的变量时,将发生进程同步问题。该变量的值在被第二个进程使用之前可能无法正确更新。这种情况称为“竞跑条件”。有针对此问题的软件和硬件解决方案。在本文中,我们将讨论用于处理同步问题的最有效的硬件解决方案及其实现。

解决过程同步问题的硬件方法中有三种算法:

  1. 测试并设置
  2. 交换
  3. 解锁和锁定

许多操作系统中的硬件指令有助于有效解决关键部分的问题。

1.测试并设置:
在这里,共享变量是锁,它初始化为false。 TestAndSet(lock)算法以这种方式工作–它总是返回发送给它的任何值并将lock设置为true。第一个过程将立即进入关键部分,因为TestAndSet(lock)将返回false,并且它将退出while循环。由于将lock设置为true,因此其他进程现在无法进入,因此while循环继续为true。确保相互排斥。一旦第一个进程脱离关键部分,锁定将更改为false。因此,现在其他进程可以一个一个地输入。也确保了进展。但是,在第一个进程之后,任何进程都可以进入。没有队列被维护,因此任何再次发现锁为假的新进程都可以进入。因此,无法确保有限的等待。

测试并设置伪代码–

//Shared variable lock initialized to false
boolean lock;

boolean TestAndSet (boolean &target){
    boolean rv = target;
    target = true;
    return rv;
}

while(1){
    while (TestAndSet(lock));
    critical section
    lock = false;
    remainder section
}
 

2.交换:
交换算法非常类似于TestAndSet算法。不会在交换函数中直接将lock设置为true,而是将key设置为true,然后与lock交换。因此,同样,当某个进程位于关键部分时,因为lock的值为true,所以没有其他进程可以输入该进程。确保相互排斥。再次,在关键部分之外,将锁更改为false,因此任何找到它的进程都将进入关键部分。确保进度。但是,由于同样的原因,不能保证再次有界等待。

交换伪代码–

// Shared variable lock initialized to false 
// and individual key initialized to false;

boolean lock;
Individual key;

void swap(booelan &a, boolean &b){
    boolean temp = a;
    a = b;
    b = temp;
}

while (1){
    key = true;
    while(key)
         swap(lock,key);
    critical section
    lock = false;
    remainder section
} 

3.解锁和锁定:
解锁和锁定算法使用TestAndSet来调整锁定的值,但是它为每个进程添加另一个值waiting [i],以检查进程是否一直在等待。在关键部分中,将针对该流程维护一个就绪队列。接下来进入的所有进程都将根据它们的进程号添加到就绪队列中,而不必依次添加。一旦第i个进程脱离关键部分,它就不会将锁定变为false,因此任何进程现在都可以利用关键部分,这是以前算法的问题。而是检查队列中是否有任何进程在等待。该队列被视为循环队列。 j被认为是行中的下一个进程,而while循环会检查从第j个进程到最后一个进程,然后从0到第(i-1)个进程再次检查是否有任何进程在等待访问关键部分。如果没有等待的进程,则锁定值将更改为false,接下来出现的任何进程都可以进入关键部分。如果存在,则该进程的等待值将变为false,以便第一个while循环变为false,并且可以进入关键部分。这样可以确保有限的等待时间。因此,该算法可以解决过程同步问题。

解锁和锁定伪代码–

// Shared variable lock initialized to false 
// and individual key initialized to false

boolean lock;
Individual key;
Individual waiting[i];

while(1){
    waiting[i] = true;
    key = true;
    while(waiting[i] && key)
        key = TestAndSet(lock);
    critical section
    j = (i+1) % n;
    while(j != i && !waiting[j])
         j = (j+1) % n;
    if(j == i)
         lock = false;
    else
         waiting[j] = false;
    remainder section
}