Operating system 信号量实现:为什么在测试和设置时需要禁用中断?

Operating system 信号量实现:为什么在测试和设置时需要禁用中断?,operating-system,synchronization,semaphore,Operating System,Synchronization,Semaphore,回顾这个示例信号量实现(对于SMP系统),我了解到多处理器原子检查需要测试和设置。然而,一旦我们添加了原子检查,禁用中断不是多余的吗?无论如何,禁用中断只在一个处理器上提供原子性。此外,还需要对信号量队列进行保护 class semaphore { private int t; private int count; private queue q; public semaphore(int init) { t = 0; count = init; q = new que

回顾这个示例信号量实现(对于SMP系统),我了解到多处理器原子检查需要测试和设置。然而,一旦我们添加了原子检查,禁用中断不是多余的吗?无论如何,禁用中断只在一个处理器上提供原子性。此外,还需要对信号量队列进行保护

class semaphore {
private int t;
private int count;
private queue q;

public semaphore(int init)
{
    t = 0;
    count = init;
    q = new queue();
}

public void P()
{
    Disable interrupts;
    while (TAS(t) != 0) { /* just spin */ };
    if (count > 0) {
        count--;
        t = 0;
        Enable interrupts;
        return;
    }
    Add process to q;
    t = 0;
    Enable interrupts;
    Redispatch;
}

public V()
{
    Disable interrupts;
    while (TAS(t) != 0) { /* just spin */ };
    if (q == empty) {
        count++;
    } else {
        Remove first process from q;
        Wake it up;
    }
    t = 0;
    Enable interrupts;
}

}

虽然关闭一个处理器上的中断确实不足以保证多处理器系统中的原子内存访问(因为,正如您所提到的,其他处理器上的线程仍然可以访问共享资源),我们关闭部分多处理器信号量实现的中断,因为我们不希望在进行测试和设置时被取消调度


如果持有测试和集的线程被取消调度,那么其他线程就不能对该线程睡眠时使用的信号量(因为它的计数受该测试和集的保护)执行任何操作(这不好)。为了保证不会发生这种情况,我们将在使用测试和设置时关闭处理器上的中断。

这是一个家庭作业问题,要求堆栈溢出完成家庭作业。请参阅代码来源(很可能)中的“除了使用test和set之外,为什么我们还必须禁用中断?”。这个问题目前还没有完成:“要求家庭作业帮助的问题必须包括你迄今为止为解决问题所做的工作的摘要,以及你解决问题的困难的描述”谢谢,@xmojmr-我正考虑回答这个问题。现在它结束了。这个问题似乎离题了,因为它是关于家庭作业的问题。它不是家庭作业问题,我是一名专业人员,我自己检查实施情况,检查各种教科书/幻灯片。我在多本书中看到了这段代码,但没有一本解释为什么需要禁用。安妮-首先感谢你回答这个问题(它几乎死了)。你的回答很有道理。不过,要真正学究化,即使在设置t=0(解锁自旋锁)之前使一个线程处于睡眠状态,其他线程在尝试访问信号量时仍会继续自旋。这对性能非常不利,因为它会导致浪费周期,但它仍然是一个正确的(尽管很糟糕)解决方案,因为没有任何状态因任何竞争条件而损坏。如果我错了,请纠正我,即禁用中断对性能至关重要,而不是对正确性。你是对的--保持中断打开不会带来任何同步问题,只会导致性能不佳。太棒了。感谢您的回复和澄清:)