仔细研究这个示例信号量实现(对于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;
}
}
最佳答案
虽然关闭一个处理器上的中断确实不足以保证多处理器系统中的原子内存访问(因为,正如您提到的,其他处理器上的线程仍可以访问共享资源),但我们关闭了部分多处理器信号量的中断实现,因为我们不想在进行测试和设置时进行调度。
如果对包含测试和设置的线程进行了调度,则其他线程无法使用该信号量(因为其计数受该测试和设置保护)在线程处于 sleep 状态时正在使用(这不好)。为了确保不会发生这种情况,我们将在使用测试和设置时关闭处理器上的中断。